Search code examples
ioscore-datansincrementalstore

NSIncrementalStore called with NSSaveChangesRequest.deletedObjects == nil


I am in the process of writing an NSIncrementalStore that is backed by a REST service. It works nicely for POSTing and GETing objects, but when DELETEing them I encounter the following problem:

  1. test calls [context delete: object];
  2. context.deletedObjects contains object (as one would expect)
  3. test calls [context save: &error];
  4. iOS calls NSIncrementalStores executeRequest:withContext:error: with a NSSaveChangesRequest; when the call arrives both context.deletedObjects == nil and saveChangesRequest.deletedObjects == nil, so my code cannot find out which objects to DELETE from the server.

How can it happen that deletedObjects is set to nil between the call to the context's save and its invocation its NSIncrementalStore?

UPDATE possible cause: object.objectID is still a temporaryID following save. The NSIncrementalStore is currently obtaining object IDs from newObjectIDForEntity:referenceObject: and the description from Apple's documentation somehow does not seem to apply yet:

New objects inserted into a managed object context are assigned a temporary ID which is replaced with a permanent one once the object gets saved to a persistent store.


Solution

  • The trouble was that I did not yet store enough information on the server to recreate (permanent) object IDs during fetches.

    This solves the problem in NSIncrementalStore:

    • When executeRequest:withContext:error: receives an NSSaveChangesRequest it extracts (in my case) reference strings from saved objects with referenceObjectForObjectID: and stores these (along with objects' other attributes) on the server.

    • When executeRequest:withContext:error: receives an NSFetchRequest it obtains reference strings (along with objects' other attributes) from the server and recreates objects with [context objectWithID: [self newObjectIDForEntity: entity referenceObject: referenceString]].