ioscore-dataios8-today-widget

Core Data App group synchronization (w/ extension)


The widgets in our iOS App are custom, and therefore I added a feature to remove parts of the widget. To save settings for the widgets etc. our widgets share Core Data via App groups. However when I delete something from the widget it doesnt seem to always sync correctly. This happens primarily when the app is active in memory.

When I delete something I call this:

-(void)removeWidgetFromUser:(UserModel *)user Widget:(Widget *)widget{
    if(widget != nil){
        [widgetContext deleteObject:widget];

        NSError *error;
        if (![widgetContext save:&error]) {
            NSLog(@"Unable to remove widget %@", error);
        }
    }
}

Then I use wormhole to sync the core data in my app and it calls this:

-(void)updateCoreData{
    [self.managedObjectContext refreshAllObjects];
}

I am sure both the methods get called. But sometimes the app sees a widget I just removed, and then it also happens to reappear in my Widget.

EDIT: I think whats happening is that the CoreData context in my app doesnt update correctly and then the widget actually syncs with the CoreData in my app. Therefore the deleted widget re-appears after some time. Still figuring it out...


Solution

  • I finally did it. By implementing the following code:

    - (id)initWithCoder:(NSCoder *)decoder {
        NSManagedObjectContext *context = [SharedCoreDataObjects sharedInstance].managedObjectContext; // use your NSManagedObjectContext
        NSPersistentStoreCoordinator *coordinator = [SharedCoreDataObjects sharedInstance].persistentStoreCoordinator; //use your NSPersistentStoreCoordinator
        NSURL *url = (NSURL *)[decoder decodeObjectForKey:@"URIRepresentation"];
        NSManagedObjectID *managedObjectID = [coordinator managedObjectIDForURIRepresentation:url];
        self = [context existingObjectWithID:managedObjectID error:nil];
        return self;
    }
    
    - (void)encodeWithCoder:(NSCoder *)encoder {
        [encoder encodeObject:[[self objectID] URIRepresentation] forKey:@"URIRepresentation"];
    }
    

    in my NSManagedObjects I was able use MMWormhole to send the NSManagedObjectContextDidSaveNotification to the App and then call

    [context mergeChangesFromContextDidSaveNotification:messageObject];
    

    To let the context merge the changes. This seems to work perfectly for now!