Search code examples
objective-cicloud

How to get NSManagedObject from NSNotification after iCloud sync


I need to run updates based on when a NSManagedObject gets inserted/updated in the iCloud NSPersistentStoreDidImportUbiquitousContentChangesNotification. I need to get an attribute from the NSManagedObject that was updated/inserted named "url". Here's the code that I have so far...

//called when there is a change to iCloud data
- (void)cloudChanges:(NSNotification*)notification
{
    NSDictionary *userInfo = [notification userInfo];
    NSDictionary *info = notification.userInfo;
    NSSet *insertedObjects = [info objectForKey:NSInsertedObjectsKey];
    NSSet *updatedObjects = [info objectForKey:NSUpdatedObjectsKey];
    NSSet *deletedObjects = [info objectForKey:NSDeletedObjectsKey];

    /*this is where i need to loop thru the objects and do something
    based on the url attribute of the NSManagedObject, the classname is ItemMeta
    */
    for (NSManagedObject *object in updatedObjects) {
        if ([[object entity].name isEqualToString:@"ItemMeta"]) {         
           // NSDictionary *entityDic = [object entity];
            //NSDictionary *changesDic = [object changedValues];
            //NSLog(@"changesDic.url: %@", [changesDic objectForKey:@"url"]);

            ItemMeta *itemMeta = (ItemMeta *)[object entity];
           //this line throws an error "unrecognized selector sent to instance"
            NSArray *itemMetas = [self getAllItemMetadataForURL:itemMeta.url];

        }
    }

***here's the update to correctly iterate the NSUpdatedObjectsKey Jun 6 2014

     for (NSManagedObjectID *objectID in updatedObjects) {
            NSManagedObject *object = [self.mocMaster objectWithID:objectID];
            if ([object isKindOfClass:[ItemMeta class]]) {
                ItemMeta *itemMeta = (ItemMeta *)object;
                NSArray *itemMetas = [self getAllItemMetadataForURL:itemMeta.url];
            }
        }

***end of update June 6 2014

    [self.mocMaster mergeChangesFromContextDidSaveNotification:notification];

}

Solution

  • You didn't really ask a question or say what the issue with your code is. Nonetheless:

    ItemMeta *itemMeta = (ItemMeta *)[object entity];

    really ought to be:

    ItemMeta *itemMeta = (ItemMeta *)object;

    ItemMeta *itemMeta = (ItemMeta*)[self.mocMaster objectWithID:object]

    entity is more of a class description, not an object instance. object is the object instance that you need to cast to the entity class type. object turns out to be an NSManagedObjectID for iCloud notifications.

    You could also use [object isKindOfClass:[ItemMeta class]] -- no chance for a typo in a string literal.

    You should probably do the mergeChange first, as well, so that you get the updated object.