Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Data iOS 8 Today Widget issue

I have a DataManager class which returns a shared instance:

+ (DataManager *)sharedInstance;
{
    static DataManager *sharedInstance = nil;
    static dispatch_once_t pred;

    dispatch_once(&pred, ^{
        sharedInstance = [[DataManager alloc] init];
    });

    return sharedInstance;
}

In here I keep track of my managedObjectContext, managedObjectModel, persistentStoreCoordinator.

I also have a method where I pull out items for displaying:

- (NSArray *)getItems
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Item"];
    return [[self managedObjectContext] executeFetchRequest:fetchRequest error:nil];
}

Now in my main app I have a view controller when I call this getItems and then modify items individually. So for example set item.itemName = @"testName"; and then call my save method.

I also have an iOS 8 where in my TodayViewController I also call the getItems method. I have an NSNotification which detects for managedObjectContext saves.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refetchItems) name:NSManagedObjectContextDidSaveNotification object:[[DataManager sharedInstance] managedObjectContext]];

These refetched items does get called but returns the outdated NSManagedObjects. So for example the itemName has not changed to @"testName".

Where am I going wrong? Let me know if you need to see any other code.

Thanks!

like image 458
Stephen Avatar asked Mar 18 '23 10:03

Stephen


1 Answers

You may try the following for refreshing particular ManagedObject. And if you want to refresh a list of ManagedObject then loop each object and execute the command.

[_managedObjectContext refreshObject:act mergeChanges:YES];

Or for iOS verion 8.3 and above you can make use of the following method for updating all the ManagedObject in the context at once as follows.

[_managedObjectContext refreshAllObjects];

It works a bit, but only for data UPDATE, not for adding or deleting data.

If it is not working, you can add also

[_managedObjectContext reset];

after that, you have to read "reassign" all variables, that you have loaded from your core data store.

Another solution (slower and more ugly)

If the above is not working, another solution would be to delete current context and create it again.

I just set

_persistentStoreCoordinator = nil;
_managedObjectModel = nil;
_managedObjectContext = nil;

I have CoreDataManager class with this properties

@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;

And in class I have manually created setters. If I nill all variables, due to setters, they are inited again once I read them outside my core data manager class.

You can improve this by using NSUserDefault store. It is being updated correctly. In main app, if you change smething, set flag in NSUserDefault. In extension, read this and if flag is marked, reset core data. This way, you will save some ticks and make things faster a bit.

For allocation of NSUserDefault (in both apps - extension and main) use this - after that, you can read data from it as usuall and they should be in sync

NSUserDefaults *prefs = [[NSUserDefaults alloc] initWithSuiteName:GROUP_NAME]; //share with extension
like image 199
Martin Perry Avatar answered Mar 23 '23 21:03

Martin Perry