Core Data is not persisting data between app launches - ios

I have a app that is using core data. The Core Data stack (the context, object graph, persistent store coordinator, and the persistent store) is being created, and I am able to use it without issue. The problem is that the saved data is not persisting, can someone help me with what I am doing wrong? Here is where I create the Core Data stack.
- (void)initializeCoreDataStack
{
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"Favorites"
withExtension:#"momd"];
if (!modelURL)
NSLog(#"MODEL URL NOT INITIALIZED");
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
if (!mom)
NSLog(#"OBJECT MODEL NOT CREATED");
NSPersistentStoreCoordinator * psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
if (!psc)
NSLog(#"PERSISTENT STORE COORDINATOR NOT CREATED");
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc setPersistentStoreCoordinator:psc];
self.managedObjectContext = moc;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSArray *directory = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask];
NSURL *storeUrl = [directory lastObject];
storeUrl = [storeUrl URLByAppendingPathComponent:#"Favorites.sqlite"];
NSError *error = nil;
NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeUrl
options:nil
error:&error];
if (!store)
{
NSLog(#"ERROR CREATING STORE: %# %#", error.localizedDescription, error.domain);
// present error to user
}
else
{
dispatch_sync(dispatch_get_main_queue(), ^{
// do something once the stack is finished being created
NSLog(#"persistent store created");
});
}
});
}

You have to save core data explicitly, otherwise it won't persist. Not hard to solve, though.
In your controller implementation file (e.g. coreDataViewController.m), call this function when you want to save changes to core data
// add this call, whenever you want to save data
// e.g. responding to a UIButton event
[self saveCoreDataContext];
- (void)saveCoreDataContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
}

My personal experience is that, even if you called [moc save:error], you may not find the content saved while you are running the app from Xcode -> Build and Run on device. However, if you stop the Xcode from running the app, and launch the app from the device by clicking the App Icon, the content is actually persisted.
Just personal experience that I found through trial and error, hope that you see the same thing.

You have to save the MOC.
[mom save:nil];

There's a few things here that stand out to me as odd. First, why are you threading the creation of the NSPersistentStore? Generally, I create the NSPersistentStoreCoordinator, add NSPersistentStores, and then create the contexts. I would suggest doing it in that order unless you have a good reason to do otherwise. While it's not specifically prohibited, you may experience problems adding a NSPersistentStore after the NSManagedObjectContext has been created.
I'm not sure if it is required or not, but I've always explicitly held a strong reference to the NSPersistentStoreCoordinator. It's useful to create multiple contexts, as well. I would suggest doing so in your code.
As everyone else has said, you also need to explicitly save.

Related

Migrate persistent store to new location

I need to move my app's database to a new location and stop it from being shared through iCloud automatically.
From my understanding, Apple previously documented that a database should be placed in the Documents directory of an application, but now says that the database should be placed in the Library directory. This is because iOS now shares all data from the Documents directory through iCloud.
My issue is that I need to move my database from the Documents directory to the Library directory. Below is the code I use to do this.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
// Get the URL of the persistent store
NSURL *oldURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"App.sqlite"];
bool oldStoreExists = [[NSFileManager defaultManager] fileExistsAtPath:[oldURL path]];
// Get the URL of the new App Group location
NSURL *newURL = [[self applicationLibraryDirectory] URLByAppendingPathComponent:#"App.sqlite"];
bool shouldMoveStore = false;
NSURL *storeURL = nil;
if (!oldStoreExists) {
//There is no store in the old location
storeURL = newURL;
} else {
storeURL = oldURL;
shouldMoveStore = true;
}
NSError *error = nil;
NSDictionary *options = #{ NSMigratePersistentStoresAutomaticallyOption:#YES, NSInferMappingModelAutomaticallyOption:#YES };
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
NSLog(#"Error Moving Store: %ld\nDescription: %#\nReason: %#\nSuggested Fix:%#", (long)error.code, error.localizedDescription, error.localizedFailureReason, error.localizedRecoverySuggestion);
abort();
}
if (shouldMoveStore)
[self movePersistentStoreFrom:oldURL To:newURL];
return _persistentStoreCoordinator;
}
-(void) movePersistentStoreFrom:(NSURL *)oldURL To:(NSURL *)newURL {
// Get the reference to the current persistent store
NSPersistentStore *oldStore = [_persistentStoreCoordinator persistentStoreForURL:oldURL];
// Migrate the persistent store
NSError *error = nil;
[_persistentStoreCoordinator migratePersistentStore:oldStore toURL:newURL options:nil withType:NSSQLiteStoreType error:&error];
if (error) {
NSLog(#"Error Moving Store: %ld\nDescription: %#\nReason: %#\nSuggested Fix:%#", (long)error.code, error.localizedDescription, error.localizedFailureReason, error.localizedRecoverySuggestion);
abort();
}
}
This code seems to work in moving the persistent store, but on the next run of the application the old store is found again and the app attempts to migrate the store a second time. At this point a crash occurs, and I'm assuming it is due to this double migration call. In classic Xcode style, the stack trace is pretty much useless.
Update -
The migratePersistentStore function does not remove ("cut/paste") the old sqlite database, instead it just makes a "copy". It looks like I'll need to remove the old one programmatically.
I switched the code to check if the newStoreExists as opposed to the !oldStoreExists, and the migration does work.
My new issue is that the table rows of the migrated data have become randomized. Any help with this would be appreciated!
Update 2 -
As it turns out, any data migrations like moving the store location or updating the database will randomize your data if you are using Core Data. You need to put an attribute into your table and use a NSSortDescriptor inside of your NSFetchRequest to manually sort the data and keep it ordered.
If you never migrate the data (I previously had not) the core data fetch request always come in the order it was saved.

Multithreading coredata with unique constraint for upsert

Hello guys I am developing an app which uses coredata (multithreaded), below is the coredata stack used (this was designed via a tutorial found here: https://www.cocoanetics.com/2012/07/multi-context-coredata/)
THE MODEL
- (NSManagedObjectModel *)managedObjectModel {
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"XXX" withExtension:#"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
THE MAIN CONTEXT
- (NSManagedObjectContext *)managedObjectContext{
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_managedObjectContext.parentContext = [self writerManagedObjectContext];
return _managedObjectContext;
}
THE WRITER CONTEXT
- (NSManagedObjectContext *)writerManagedObjectContext{
if (_writerManagedObjectContext != nil) {
return _writerManagedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_writerManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_writerManagedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _writerManagedObjectContext;
}
THE PERSISTENT STORE COORD
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"XXX.sqlite"];
NSError *error = nil;
NSString *failureReason = #"There was an error creating or loading the application's saved data.";
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:#"XXX" URL:storeURL options:options error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
As you can see, the WRITER context is the parent of the MAIN context which means that the WRITER would handle saving data to the store whilst it also updates the MAIN context (in memory) of any changes.
NOTE: the WRITER save to the store because the POS was set to the WRITER context.
On the entities in the model, I set 'Id' as a unique constraint for all entities (tables) in the database which is used for UPSERT (i.e. an equivalent of SQL insert OR replace).
And both the MAIN and WRITER contexts have their merge policies set to NSMergeByPropertyObjectTrumpMergePolicy which ensures objects between the WRITER, the MAIN and the store are in sync.
[[CoreDataCommons mainContext] setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[[CoreDataCommons writerContext] setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
Now when I want to insert to the database I create a new context:
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[context setParentContext:writerManagedObjectContext];
[context performBlock:^{
// Populate entity attributes and save
for (id object in objects){
// Save every 500 objects
if (count % 500 == 0){
if ([context save:&error]){
}
}
count++;
}
// Final save if anything unsaved
if ([context save:&error]){
}
// Save WRITER context which will push changes to MAIN context
[writerManagedObjectContext performBlock:^{
if (![writerManagedObjectContext save:&writerError]) {
DLog(#"Writer: Unresolved error %#, %#", writerError, [writerError localizedDescription]);
}];
}];
THE PROBLEM
When the app is loaded for the very first time, it loads about 15000 objects (type JSON) from API and it writes this data in about 3 seconds (which I think is a bit too long BUT NOT THE MAIN ISSUE); however the first time load is not the issues. The ISSUE arises from subsequent loads from API; so, the second time it loads it takes about 5 mins to write the same data and it also BLOCKS THE MAIN THREAD.
After a few debugging I found that the constraint (i.e. the UPSERT) causes it to take too long to save when there is data already in the database. DOES THIS MEAN THAT ITS ALSO DOING THE PRIMITIVE
IF (EXIST){ // UPDATE}ELSE{ // INSERT}
I have used multiple context to ensure this is not the case but it still seems to hold the main thread and takes a ridiculous amount to time to save.
Questions
Firstly, could there be any issue caused by the coredata stack (i.e. a deadlock,background process etc)?
Secondly: Is this time taken to save the object normal with coredata? if not could anyone suggest an optimisation strategy.
Thirdly I am considering bypassing coredata and using sqlite directly. Any foreseen obstacles with this? apart from security layer provided by coredata.
Any ideas are welcome.
Thanks in advance.

steps for use core data as database in my iOS app in Objective C

anyone can describe me about core data?
I want to create worksheet which store day activity record and that data stored in local file.
I think core data is best to store locally.
Thanks in advance.
You should see CoreData not as a database, but as a way to manage a graph of object.
You can then store this graph in different places (transparently from the application point of view) such as memory, XML, sqlite, and I think custom binary file.
What you usually do is to write the model in a core data model.
Each object is either an instance of NSManagedObject (which you can query / work with with methods such as valueForKey:, setValueForKey: etc) or subclasses of that class. This subclasses can be autogenerated directly from Xcode, and at this point you almost forget you are working with CoreData. Every attribute is a #property, every to-many relationship is a NSSet.
You get back to the fact that you are using CoreData when you create and want to save the object. In this case you have to get the 'context' in which the object resides, and call method on it (e.g. save)
There is full of tutorial and documentation on the web about CoreData.
In my opinion the core point is.. don't think at it as a relational database. "Be more object oriented" :)
To getting started you can take a look at:
http://www.raywenderlich.com/934/core-data-tutorial-for-ios-getting-started
The for more complex stuff the apple doc is ok
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html#//apple_ref/doc/uid/TP30001200-SW1
Yes you are right, Core data is bast way to store data in iOS applications.
With new XCode all you need to do is when creating new project click check box that you will use coreData.
This will create yourPorject.xcdatamodeld file and some methods inside your AppDelegate file :
- (NSURL *)applicationDocumentsDirectory {
// The directory the application uses to store the Core Data store file. This code uses a directory named "result.PingPong" in the application's documents directory.
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
- (NSManagedObjectModel *)managedObjectModel {
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"PingPong" withExtension:#"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it.
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
// Create the coordinator and store
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"PingPong.sqlite"];
NSError *error = nil;
NSString *failureReason = #"There was an error creating or loading the application's saved data.";
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// Report any error we got.
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSLocalizedDescriptionKey] = #"Failed to initialize the application's saved data";
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
dict[NSUnderlyingErrorKey] = error;
error = [NSError errorWithDomain:#"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
- (NSManagedObjectContext *)managedObjectContext {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
return nil;
}
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
}
#pragma mark - Core Data Saving support
- (void)saveContext {
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
NSError *error = nil;
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
}
(I case it didn't)
After that you create your entity object inside yourPorject.xcdatamodeld, by clicking on AddEntity, name it and inside with Add Attribute add all your attributes.
After that click on menu : Editor -> Create NSManagedObject subclasses. This will automatically create object for you.
All you need to do to save object into database is
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = appDelegate.managedObjectContext;
YourObject * o = [NSEntityDescription insertNewObjectForEntityForName:#"YourObject" inManagedObjectContext:context];
o.attribute1 = attribute1;
o.attribute2 = attribute2;
[context save:nil];
To fetch all object you will need this :
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = appDelegate.managedObjectContext;
NSError *fetchError;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"YourObject" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&fetchError];
if (fetchError != nil) {
NSLog(#"Error fetching database request. Reason: %#", fetchError);
}
I hope it will help you for start.
Marko

core data memory foot print in iOS keeps growing

I am trying to backup a Core Data SQLite database. This code successfully processes the running database and merges the WAL file. Unfortunately, everytime it runs I see a bump of about 3-5 MB in my memory footprint. This is causing issues after the program has run for a while. Can someone help me reclaim the memory? I thought setting everything to nil would dealloc all of the objects from RAM, but that doesn't seem to be it.
-(void) backupDatabaseWithThisTimeStamp: (int) timeStamp withCompletionBlock:(void (^)(void))completion {
NSDate *backupDate = [NSDate date];
NSError *error;
[self.defaultPrivateQueueContext save:&error];
if (error) {
NSLog(#"error -> %#",error);
}
dispatch_async(self.backupQueue, ^{
// Let's use the existing PSC
NSPersistentStoreCoordinator *migrationPSC = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
// Open the store
id sourceStore = [migrationPSC addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self persistentStoreURL] options:nil error:nil];
if (!sourceStore) {
NSLog(#" failed to add store");
migrationPSC = nil;
} else {
NSLog(#" Successfully added store to migrate");
NSError *error;
NSLog(#" About to migrate the store...");
id migrationSuccess = [migrationPSC migratePersistentStore:sourceStore toURL:[self backupStoreURLwithTimeStamp: timeStamp] options:[self localStoreOptions] withType:NSSQLiteStoreType error:&error];
if (migrationSuccess) {
NSLog(#"store successfully backed up");
// Now reset the backup preference
NSManagedObjectContext *tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
tempContext.persistentStoreCoordinator = migrationPSC;
tempContext.undoManager = nil;
// clip out data
[CDrawColorData purgeDataOlderThan:backupDate fromContext:tempContext];
migrationPSC = nil;
tempContext = nil;
}
else {
NSLog(#"Failed to backup store: %#, %#", error, error.userInfo);
migrationPSC = nil;
}
}
migrationPSC = nil;
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) {
completion();
}
});
});
}
self.backupQueue = _backupQueue = dispatch_queue_create("backup.queue", DISPATCH_QUEUE_SERIAL);
localStoreOptions =
- (NSDictionary*)localStoreOptions {
return #{NSMigratePersistentStoresAutomaticallyOption:#YES,
NSInferMappingModelAutomaticallyOption:#YES,
NSSQLitePragmasOption:#{ #"journal_mode" : #"DELETE" }};
}
commenting out everything that happens after the migrationSuccess point does not effect the memory footprint.
All of the issues that I've seen are directly accountable to the Xcode Scheme.
Product->Scheme
Select Run-Options
UNCHECK -> Queue Debugging (enable backtrack recording)
Once this was done, all of the memory footprint growth immediately disappeared.
Due to too few reps i'm writing this as an "answer" (even if it might not be the solution): I think it's good practice to think about "cache_size" as another NSSQLitePragmasOption and to limit it accordingly:
NSSQLitePragmasOption:#{ #"journal_mode" : #"DELETE", #"cache_size" : #"50"}
see www.sqlite.org for declarations
I think it's likely to be because all relationships in a Core Data object graph are strong references. So you're all but guaranteed retain cycles. For further diagnostics you should use Instruments' leaks tool and see what type of object appears to be leaking.
You're therefore likely to want to call reset on any instances you create of NSManagedObjectContext before discarding them. This will forcibly fault all active objects, thereby breaking any retain cycles (unless you access the objects again, naturally). It's not explicit in the documentation that a dealloc automatically prompts a reset and therefore it doesn't appear to be a contractual guarantee.

Recommended merge policies on main context & private context in multi-threaded CoreData app

I've read and tried to understand the recommended praxis of doing this, but I would like to have Your expert opinions on the following scenario;
I use CoreData and have a main context assigned to the persistent store coordinator.
- (void) setupCoreDataStack
{
self.managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:[NSBundle allBundles]];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
NSURL *url = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:#"Model.sqlite"];
NSDictionary *options = #{NSPersistentStoreFileProtectionKey: NSFileProtectionComplete,
NSMigratePersistentStoresAutomaticallyOption:#YES};
NSError *error = nil;
NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:options error:&error];
if (!store)
{
NSError *deleteError = nil;
if ([[NSFileManager defaultManager] removeItemAtURL:url error:&deleteError])
{
error = nil;
store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:options error:&error];
}
if (!store)
{
// Also inform the user...
NSLog(#"Failed to create persistent store. Error %#. Delete error %#",error,deleteError);
abort();
}
}
self.mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
self.mainManagedObjectContext.persistentStoreCoordinator = psc;
}
All my async worked threads (sync with backend, perform various BLE/CoreBluetooth actives, etc) create their own private contexts (from within their async dispatched threads), and then use performBlock to perform the work before finally saving private context AND main context according to guidelines/recommendations;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
(unsigned long)NULL), ^(void)
{
//Create private context and lnk to main context..
NSManagedObjectContext* privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
//Link private context to main context...
privateContext.parentContext = self.mainManagedObjectContext;
//Perform login-mechanism in block
[privateContext performBlock:^{
//Do the work!
...
...
//Merge changes to main context!
NSError* error = nil;
if (![privateContext save:&error])
abort();
//Save main context to persistent store coordinator
[self.mainManagedObjectContext performBlockAndWait:^{
NSError *mainError;
if (![self.mainManagedObjectContext save:&mainError])
abort();
}];
}];
});
My question now is, how does the merge policies work in this setup? When I assign the mainContext a mergePolicy, does that apply to how changes are merged from mainContext to PSC, or when private contexts are merged to main context?
Is my understanding correct, that using NSMergeByPropertyObjectTrumpMergePolicy in this setup, if assigned to the private contexts, will ensure that the private context changes are merged to main context and that the private object will be used if there's a conflict? Or do I have to set the main context's mergePolicy of this to work too?
Thank you for your thoughts,
/Markus
Generally you want to set the merge policy on the main NSManagedObjectContext. However my first question is, are you getting merge conflicts? If you are not getting any then do you need to change the merge policy at all?
I tend to leave the default policy (error on merge) in place until I actually hit a merge problem. Otherwise you could be potentially masking a problem by the merge working when you didn't realize there was a merge situation.

Resources