4

I am trying to use local-datastore with iOS.

Say I have two or more devices.

I use saveEventually to save data locally (and on cloud). When working only on one device it works fine.

When I start working with more than one device, to sync I use:

PFQuery *query = [UserPreference query];
[query whereKey:@"userId" equalTo: [PFUser currentUser].objectId];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error){ 
if(!error){
    [UserPreference pinAllInBackground:objects block:^(BOOL succeeded, NSError *error) {<---- objects here are fine
    if(succeeded){
     [query fromLocalDatastore];
     NSLog(@"Local %@", [(UserPreference*)[[query findObjects] objectAtIndex:0] filterContext ]); <--- however here the old value is retrieved
     }
   }];
  }
}];

So I get proper objects from the cloud, then i PinAll but when i retrieve from localDataStore Old values are retrieved?

Could anyone be kind to explain : 1. if this is feasible at all i.e to sync between two devices using local data store 2. what I am doing wrong?

PS: I notice that serverData in objects contains the correct info but does not update the object

Irfan
  • 432
  • 1
  • 6
  • 17
  • I'm not very familiar with Parse, but I think you should use in the in your last query something like `[[query fromLocalDatastore] findObjects]` or `[[query fromPin] findObjects]` – danypata Jan 16 '15 at 08:44
  • Hi @danypata. Thanks for the answer. I think the problem is that pinAll or pin does not work properly or I am not using it properly. In my case it simply does not update object. This confuses me as docs say: "Once the local datastore is enabled, you can store an object by pinning it" and " Whenever you save changes to the object, or fetch new changes from Parse, the copy in the datastore will be automatically updated, so you don't have to worry about it." – Irfan Jan 16 '15 at 09:21

2 Answers2

3

It seems that this works. So when you get update from server you need to unpin all objects with name, and then pin them back with the same name. After that you can query pinWithName:

  PFQuery *query = [UserPreference query];
[query whereKey:@"userId" equalTo: [PFUser currentUser].objectId];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    if(!error){
        [UserPreference unpinAllObjectsInBackgroundWithName:@"userPreference" block:^(BOOL succeeded, NSError *error) {
                [UserPreference pinAllInBackground:objects withName:@"userPreference"];
        }];
    }
Irfan
  • 432
  • 1
  • 6
  • 17
1

I have the same requirement, I've found the above helpful, but have some further data and a different option that others may find useful.

I also have two devices. All data is in the local datastore and pushed up to parse server, this works well and I can see the data on the server. However, when I log into a second fresh device with the same account details I do not get all the data.

After logging in with :

[PFUser logInWithUsernameInBackground:user password:pass block:^(PFUser *user, NSError *error) {
if (user) { /* success, user object is in local datastore */ }
}];

If successful, any data associated with the user object is available. But any other objects related to this user have to be requested. Hence, fields accessed through the user object are there, but records related to the user object are not. I found the following to work to get the additional data:

PFQuery *query = [PFQuery queryWithClassName:@"History"];
[query whereKey:@"user" equalTo:[PFUser currentUser]];

[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    if(!error){
        NSLog(@"Fetched %lu objects", (unsigned long)[objects count]);
        for (PFObject* item in objects)
            [item pinInBackground];
    } else {
        NSLog(@"Parse error pulling data after login: %@ %@", error, [error userInfo]);
    }
}];

Finally, if you expect the data on the server to change, you do have to poll for it. I have updated the data on the server through the parse login on the web and I, at least, do not see these changes propagate to the device. I have to pull them down with a query and then pin them.

pyrrhoofcam
  • 233
  • 2
  • 10