I am working on syncing data between the client and a server. I am using MagicalRecord (a Core Data wrapper) for storing the data on the client. I have an entity called Dirty that contains a single attribute called dirty. This represents if there were changes on the client that have not been pushed up to the server yet. dirty gets set to [NSDate date] anytime an attribute is set on the class (of course, when setting dirty, the correct value is set). Every other entity created on the client inherits from Dirty. The idea is that we won’t fetch new data from the server until all client data has been pushed up (only fetch new data if all entities have dirty == nil).
When importing data from the server (using +[NSManagedObject MR_importFromObject:inContext:), each entity’s dirty attribute gets set to nil (because the client is up-to-date with the server). 
Right before a save is kicked off (inside the +[MagicalRecord saveWithBlock:completion:] save block), dirty is still nil. However, in the completion block, fetching the entity that was just saved (on the main thread) has a value for dirty. 
During the save, the entity is transferred to the main thread’s context. However, there is a problem because -[NSManagedObject didChangeValueForKey:] gets called for every attribute that is transferred from the localContext (background thread) to the main context (on the main thread). dirty gets set with [NSDate date] for each entity. Most of the time, dirty does not get set last, which means when another attribute is set, dirty is overwritten. 
Is there a way to make sure dirty is the last attribute that is set when transferring the NSManagedObject instance to the main thread’s context? I’m even willing to set dirty when the object is saved (instead of when the properties are set).
I’ve tried all sorts of options, including checking against -[NSManagedObject isInserted] and -[NSManagedObject isUpdated] inside -[NSManagedObject didChangeValueForKey:]. One other thing that is kind of annoying is that the new object is inserted before the attributes are transferred over (I thought I could have some sort of flag to lock/unlock setting dirty).
Another thing to note is [NSManagedObject(_NSInternalMethods) _updateFromRefreshSnapshot:includingTransients:] is what gets called right before -[NSManagedObject didChangeValueForKey:] is called on the new object.
Any ideas? I’ve been facepalming over this for a couple days now.
 
     
     
    