iosobjective-cparse-platformpfquerylocal-datastore

Parse storing local datastore objects to cache and clearing them?


I'm storing objects to the Parse local datastore in the standard manner:

[someObject pinInBackgroundWithName:someName];

Generally, this works fine. However, sometimes when I do a local query, i.e.

PFQuery *query = [SomeObject query]; 
[query fromLocalDatastore];
[query fromPinWithName:someName];
[query findObjectsInBackgroundWithBlock:block];

it appears there are no local objects and I get the error:

error   NSError *   domain: @"Parse" - code: 120

which I understand to be:

"Error code indicating the result was not found in the cache."

I thought the local datastore and the cache were 2 completely different storage mechanisms? Yet it seems my data is being saved to the cache, which is then being flushed. How could this be? The local datastore isn't much use if it gets flushed out of my control...

UPDATE

I thought initially it was because I was accessing the local datastore while writing to it in the background, therefore getting a nil result. But putting my pinning onto the main thread doesn't resolve this.

Then I thought it might be a bug with recursive pinning, since my object contains pointers to objects with pointers. But explicitly pinning all pointers didn't help - whether in the background or on the main thread.

I tried just querying the object without the includeKey, and I think this meant consistent returns, but the secondary query needed to retrieve the remaining data proved a bit slow for what I'm trying to do.

Finally, I think it might be something to do with this bug

Writing any new data appears to remove all the previous pinned data...


Solution

  • Update: I'm now pretty sure that the nil returns were because I was including keys for objects that hadn't been fetched. So instead of returning an array of objects with nil objects attached, it just returns nil. So if you're querying the local datastore with a bunch of include keys, make sure all the included data exists in the local datastore first. Otherwise it returns nil.

    Original answer:

    I haven't managed to figure this out, but there is a work-around. I was trying to avoid having to use it, but after days of fiddling, it seems the only solution.

    Don't include any 'includeKey's in the original query. Doing so, in my case at least, seems to wipe the local datastore. Any subsequent queries work fine, but if you quit the app and re-open it, or write any new data, the first query always wipes the store and returns nil objects.

    So instead, query on a single object and then fetchFromLocalDatastore when you need to access anything it points to.

    I found advice here and here (thanks @PowHu) but I could find little else online about the issue.