0

Using RestKit 0.20.3. Placing post/put/delete (create/update/delete) calls in the didChangeObject:(id) … forChangeType method of the fetched results controller is not working out.

On a fetch of most recent entries from the database, the fetched results controller (FRC) gets an insert notification for a newly inserted retrieved record. That causes a POST that duplicates the object. The post itself causes two POSTS and five PUTS. The first POST is RestKit (RK) retrieving and ID. The second is the POST that caused the POST. The PUTS result from the updates from the two posts, each of which generates a change notification in the FRC. The main consequence of this is duplication of records that escalates in powers of two for each refresh.

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { switch (type) { case NSFetchedResultsChangeInsert: [self.timeEntryTableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; // call to RK enqueue a POST with the object via RKObjectManager break; case NSFetchedResultsChangeDelete: [self.timeEntryTableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];//// // call to RK enqueue a DELETE with the object via RKObjectManager break; case NSFetchedResultsChangeUpdate: [self.timeEntryTableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; // call to RK enqueue a PUT with the object via RKObjectManager break; … } }

The question is, what is the right way? I believe the answer involves the core data relationships and saving. Am working on it. Not certain where this will lead. Pointers welcome.

A current answer to RestKit - Send added/edited/deleted objects after offline storage would help me.

Community
  • 1
  • 1
Douglas Lovell
  • 1,549
  • 17
  • 27
  • How are you defining `unnecessary`? The FRC will be notified about changes, but not necessarily composite changes. It also depends how you save the MOC as to how notifications are posted... – Wain Apr 02 '14 at 09:23
  • Your comment lead me to question that this approach might in fact be correct, that I might have made some other error. I created a smaller test application to verify the bad behavior and verified my suspicions that this is not at all the correct approach. You will find the stem of the question modified with a clearer description of the bad behavior. Yes, I think the correct approach might have something to do with saving the managed object context. – Douglas Lovell Apr 07 '14 at 01:55

1 Answers1

1

I'm assuming that the server assigns the unique identifier for new objects, so when you create an object locally it doesn't have one to begin with.

The FRC is designed for updating table views. So, when you do a fetch you will get a number of inserts for objects that weren't in the FRC data set before but are now. Your code is misinterpreting this as new objects when really it isn't (most of the time).

You should check if the unique identifier is set and only POST a new object when it isn't. Technically you shouldn't get duplicates anyway if you are sending the unique id to the server as it could then identify the dupe.

For updates, you should consider adding a changed flag to your entity that is set whenever any attributes that should be uploaded are modified and reset after the upload is successful. Use this to filter PUTs.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • I have up voted the answer because it works, and added sample code for the POST on insert case. You'll find the complete sample application at [RKJets](https://github.com/telegraphy-interactive/RKJets). The answer and the application are not completely satisfactory to me because I expected RestKit to do this kind of book-keeping for me, making requests as needed based on observing object changes and making RESTful calls in a more or less opinionated way. If so, then this answer and the referenced sample are wrong. Thus I've refrained from marking the answer as accepted. Thank you! – Douglas Lovell Apr 08 '14 at 19:44
  • RestKit has no such automated feature (at this time). There was a branch with people working on it for version 0.1x, but it never made it to 0.2x. It isn't a trivial problem to solve generically, but you may like to discuss it on the RestKit google group or raise a github issue. – Wain Apr 08 '14 at 19:49
  • Based on your assertion, I have marked this answer as an accepted answer. Thank you for your response. – Douglas Lovell Apr 08 '14 at 19:54