Exception while registering subclass with Parse

308 Views Asked by At

I have a class called Attendee which inherits from PFObject. In my applicationDidFinishLaunching() method, I register the subclass like so:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    Attendee.initialize()
    Parse.enableLocalDatastore()
    Parse.setApplicationId(ObjectManager.appID, clientKey: ObjectManager.clientKey)

    getData()

    return true
}

func getData() {
    //create the query
    var attendeeQuery = Attendee.query()
    attendeeQuery?.fromLocalDatastore()
        .fromPinWithName(CacheKeys.AttendeesKey)
        .whereKey("conference", equalTo: ObjectManager.currentConf)

    //register a background task
    var bgTask = UIBackgroundTaskInvalid
    bgTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({ () -> Void in
        UIApplication.sharedApplication().endBackgroundTask(bgTask)
        bgTask = UIBackgroundTaskInvalid

        println("Attendees Loader Expiration Handler called")
    })

    //run the query
    attendeeQuery?.findObjectsInBackgroundWithBlock({ (cachedAttendees: [AnyObject]?, error:NSError?) -> Void in
        if error != nil {
            println(error)
            return
        }

        ...

            UIApplication.sharedApplication().endBackgroundTask(bgTask)
        })
    })
}

However, when I run the code, I get an exception at the line var attendeeQuery = Attendee.query(). The exception says that I need to register Attendee subclass before I use it. I don't understand why it is saying that, as I register it right beforehand. Below is the Attendee class definition.

class Attendee: PFObject, PFSubclassing {

    var name:String
        {
            return self["name"] as! String
    }

    ...

     override class func initialize() {
        var onceToken : dispatch_once_t = 0;
        dispatch_once(&onceToken) {
            self.registerSubclass()
        }
    }

    class func parseClassName() -> String {
        return Classes.Attendee
    }
}

The exception:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'The class MedConf.Attendee must be registered with registerSubclass before using Parse.'
*** First throw call stack:
(0x1835002d8 0x194d240e4 0x183500218 0x1001e21d0 0x1001e1fac 0x100135d88 0x100138af0 0x1000e43e0 0x1000e4580 0x187fb3190 0x1881ca854 0x1881cd208 0x1881cb778 0x18bd093c8 0x1834b827c 0x1834b7384 0x1834b59a8 0x1833e12d4 0x187fac43c 0x187fa6fac 0x1000e7b48 0x1953a2a08)
2

There are 2 best solutions below

0
Greg On BEST ANSWER

I had the same problem when I upgraded to Parse's iOS SDK 1.7.5 from 1.6.3. The problem was in my initialize function, which looked the same as yours.

Using a dispatch_once_t as a local var in a function doesn't serve the purpose of ensuring that the subclass is registered exactly once; I noticed by putting a breakpoint on the registerSubclass() call in the initialize function that it was being called many times. The constant re-registering of the subclass was apparently causing problems for the new version of the Parse SDK.

Changing the initialize function to look like this fixed the problem:

private static var onceToken : dispatch_once_t = 0

override class func initialize() {
    dispatch_once(&onceToken) {
        self.registerSubclass()
    }
}
1
siegy22 On

What about following the error that says must be registered with registerSubclass

So you need to call the registerSubclass Method instead of initialize

So here's the code for that:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    Attendee.registerSubclass()
    Parse.enableLocalDatastore()
    Parse.setApplicationId(ObjectManager.appID, clientKey: ObjectManager.clientKey)

    getData()

    return true
}