When I'm trying to save a PFObject
without network connection it is successfully saved locally, whenever I start the app again with network connection, it seems that the object is going to be saved to the server, but all parameters are empty.
I'm doing the following procedure, first I create a PFObject
with different values and call saveEventually
. During these steps I do not have an internet connection (airplane mode is on), therefore it can't be saved to the server and was saved locally.
PFObject *contact = [PFObject objectWithClassName:@"Contact"];
[contact setObject:[PFUser currentUser] forKey:kRelatedToUserKey];
[contact setObject:self.firstname forKey:kFirstnameKey];
[contact setObject:self.lastname forKey:kLastnameKey];
[contact saveEventually];
Now, I'm closing the app and start it again, I'm loading my contacts like that. I'm getting back the correct object with all the correct value for firstname, lastname, etc.
PFQuery *postQuery = [PFQuery queryWithClassName:@"Contact"];
[postQuery whereKey:@"related_to_user" equalTo:[PFUser currentUser]];
[postQuery fromLocalDatastore];
[postQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// here I get back the correct object from local storage, with all values
}
}];
Now, when I'm switching airplane mode off, it tries to save the object to the server, but all I can see in the backend is an objectId without any values.
Whereas the locally saved object has all the correct values.
So what are you trying to do exactly? Here's how it reads:
Your querying 'Contact' class and once you query it and find an object by it's ID (an object you don't do anything with [PFObject *contact
]) then you create a PFObject
for a completely different Class?? You could circumvent all that if you simply just want to post a PFObject
, but maybe you omitted other code that wasn't relevant to the question? But ok. To answer your question saveEventually
works hand-in-hand with local data store, so you shouldn't have any issues, as you can see, it get's called, but your values aren't being saved like the objectID is. The objectID is created autonomously, that's why it gets saved and nothing else. I have literally tried to duplicate your error in every way possible but can't, it's your values, they are returning nil. I even used macros (it looks like thats what your setting your keys as), emulated airplane mode etc. To verify, query your pinned object and see what it returns. Additionally, it's best when you do a callback to try to include an if statement or switch case that explicity defines it respectively for better practice :
{
if (succeeded) {
debt.parseID = newDebt.objectId;
}];
}];
Furthermore, be careful about putting essential tasks in the success block because an important element of saveEventually is that if it doesn't complete before the app is terminated and if the object is still in memory, it will try again, but if the object is no longer in memory it will try again the next run-time, but WITHOUT the success block.
Troubleshoot your property values (self.contact | self.amount | self.incomingDebt) how are you defining these
We've come a long ways from the original post, so in an effort to try and bring it back, the real and only issue here is saveEventually
.
Saves this object to the server at some unspecified time in the future, even if Parse is currently inaccessible.
The main intent of saveEventually
:
Use this when you may not have a solid network connection, and don’t need to know when the save completes
If more than 10MB of data is waiting to be sent, subsequent calls to will cause old saves to be silently discarded until the connection can be re-established, and the queued objects can be saved.
You have no control over when this gets called. Additionally, saving eventually caches the data on the local disk until it can be successfully uploaded, so pinning the same object is redundant. Saving eventually, if you think about it, is a local datastore of it's own, it's stores them on the local disk until internet is available (local datastore)
You have two ways that could circumvent this. Local datastore is a core-data-esque feature enabling users to forego NSFRC with a simple one-liner code pin/pinInBackground:
. You could simply pin the objects and when you know there is internet again unpin and save to your backend. Alternatively you could do it the other way, call reachability immediately, and if there is no internet pin:
the object, else saveInBackground:
first. Or simply take advantage of their caching policies.
REFERENCES :
saveEventually
: API Class Reference
It was a bug on the sdk.(1.6.2)
Submitted here: https://developers.facebook.com/bugs/1554492594835537/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With