Ashley Mills
Ashley Mills

Reputation: 53082

Parse query returns PFObject rather than subclass on restart

I have the following PFObject subclass:

class Show: PFObject, PFSubclassing {

    @NSManaged var date: NSDate

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

    static func parseClassName() -> String {
        return "Show"
    }
}

I can then add new Show objects as follows:

let newShow = Show()
newShow.date = NSDate()
newShow.pinInBackground()

And query Show objects.

let query = Show.query()!
query.fromLocalDatastore()
query.orderByAscending("date")
query.findObjectsInBackgroundWithBlock { (shows, error) -> Void in

    println("shows:\(shows)")

    let myShows = shows as? [Show]

    println("myShows:\(myShows)")

    let myObjects = shows as? [PFObject]

    println("myObjects:\(myObjects)")
}

which returns [Show] as expected:

shows:Optional([<Show: 0x7fde6a8ba0f0, objectId: new, localId: local_90293157b4a20c5c> {
    date = "2015-06-01 12:08:16 +0000";
}])

myShows:Optional([<Show: 0x7fde6a8ba0f0, objectId: new, localId: local_90293157b4a20c5c> {
    date = "2015-06-01 12:08:16 +0000";
}])

myObjects:Optional([<Show: 0x7fde6a8ba0f0, objectId: new, localId: local_90293157b4a20c5c> {
    date = "2015-06-01 12:08:16 +0000";
}])

However, if I kill the app, and then re-run the same query, the resultant array is [PFObject] rather than [Show]

shows:Optional([<Show: 0x7fef632ca2b0, objectId: new, localId: local_c6995edd73e73e10> {
    date = "2015-06-01 12:08:16 +0000";
}])

myShows:nil

myObjects:Optional([<Show: 0x7fef632ca2b0, objectId: new, localId: local_c6995edd73e73e10> {
    date = "2015-06-01 12:08:16 +0000";
}])

Am I missing something? Why isn't it returning objects of the correct class after restarting the app?

Upvotes: 1

Views: 131

Answers (2)

Ashley Mills
Ashley Mills

Reputation: 53082

OK, so I was running the query in the viewDidLoad method of my root view controller. Checking the PFSubclassing documentation for registerSubclass:

@warning This method must be called before <[Parse setApplicationId:clientKey:]>

Per the examples in the Parse docs, I was overriding the initialize method, but this getting called when the query was created, but before the appDidFinishLaunching method which called setApplicationId:clientKey

So the key is to run the query later, or register the subclasses earlier!

Upvotes: 2

Omarj
Omarj

Reputation: 1159

The problem is that you are not saving object to the Parse database, only to the device, so the object has not actually been created yet. pinInBackground() is only saving to the device, while saveInBackground() is saving to the Parse database, thereby, actually creating the object. If you use .saveEventually(), that will pin until the network can be reached to save to the Parse database. But in general - you will not actually create an object by only saving to your device, it must be saved to the Parse database to create.

Upvotes: 0

Related Questions