'NSObjectInaccessibleException' - CoreData sharing with TodayViewExtension - ios

I've kinda implemented a today view extension with CoreData sharing in my app, I have multiple problems (like only one object showing when I have three) and a big one, "Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0xd0000000001c0004". Now, this only happens when I have the application open in the background, which leads me to believe that my app is leaving the store in a bad state, but that really shouldn't be happening. I'm using Persistent Stack, external 'library' to manage all of the CoreData (instead of AppDelegate) which is readable on https://gist.github.com/mluisbrown/7015953
CoreData Fetching from TodayView Extension:
-(void)viewDidLoad{
self.persistentStack = [[PersistentStack alloc] initWithStoreURL:self.storeURL modelURL:self.modelURL];
self.managedObjectContext = self.persistentStack.managedObjectContext;
}
- (NSURL*)storeURL
{
//NSURL* documentsDirectory = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:NULL];
// return [documentsDirectory URLByAppendingPathComponent:#"WhatIOwe.sqlite"];
NSURL *directory = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:#"group.com.bittank.io"];
NSURL *storeURL = [directory URLByAppendingPathComponent:#"WhatIOwe.sqlite"];
return storeURL;
}
- (NSURL*)modelURL
{
return [[NSBundle mainBundle] URLForResource:#"WhatIOwe" withExtension:#"momd"];
}
- (NSFetchedResultsController *)fetchedResultsController {
self.persistentStack = [[PersistentStack alloc] initWithStoreURL:self.storeURL modelURL:self.modelURL];
self.managedObjectContext = self.persistentStack.managedObjectContext;
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"OweInfo" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:#"details.date" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext sectionNameKeyPath:nil
cacheName:#"Root"];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
As suggested, I've tried a merge policy in my persistent stack:
[self.managedObjectContext.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.storeURL
options:#{ NSPersistentStoreUbiquitousContentNameKey : #"WhatIOwe",
NSMigratePersistentStoresAutomaticallyOption : #YES,
NSInferMappingModelAutomaticallyOption : #YES,
NSMergeByPropertyObjectTrumpMergePolicy : #YES}
error:&error];
Another observation, on configuring my NSManagedObjectContext, passing:
[psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:self.storeURL options:nil error:&error]; allows the extension to read the store (but still throw the error I'm having), but passing
[psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:self.storeURL options:#{ NSPersistentStoreUbiquitousContentNameKey : #"iCloudStore",
NSMigratePersistentStoresAutomaticallyOption : #YES,
NSInferMappingModelAutomaticallyOption : #YES,
} error:&error]; will result in the extension not reading any data whatsoever.
Side-note: psc is passed as
__weak NSPersistentStoreCoordinator *psc = self.managedObjectContext.persistentStoreCoordinator;
self.persistentStoreCoordinator = self.managedObjectContext.persistentStoreCoordinator;

What is happening here is that you have two different processes accessing the same Core Data store, each with it's own NSPersistentStoreCoordinator.
One process has modified the store - most likely a delete. The other process has no way of knowing that this delete occurred, and already had an object in memory that pointed to the now deleted data. When that process tries to access that object it must go to the store to get the data ("firing a fault"), which no longer exists.
Core Data is not designed for this kind of use, and the capabilities of extensions are very different than applications. If your extension is able to write to the same data that the application can you may reconsider your approach and make the extension only able to read the data, and never hold the data in memory for long. This will at least mitigate the most common ways to run into these problems.

Replying to above answer and the question:
"Core Data is not designed for this kind of use"
It totally is. The assessment is correct: Something has likely been deleted in the actual app, and the extension is not aware. Fortunately CoreData provides a way to deal with this case. Check out the stalenessInterval property of NSManagedObjectContext. It defines how long your in memory cache is good for. If you're having problems because your in memory cache goes out of date from disk store change because an external process is changing them, simply set the staleness interval to 0 in your extension, and that will tell CoreData to always fetch new values from the store and ignore the in memory cache.
If you're holding a reference to an object in memory, and that object is deleted in the store, you still may have issues, so always check to make sure the object you are accessing has not been deleted.
There are a few other options if you want to get more detail. You could send notifications from your main app to your extension when things get saved to provide a manual trigger for reloading your data. You could also send specific object ids across that have been deleted or modified and use the refreshObject... method to manually refresh. Or check out mergeChangesFromContextDidSaveNotification:. You might be able to manually serialize the dictionary that expects and then send it across.
You could also have the parent app handle all database accesses and send results back via notifications. This might be unnecessary.
All of this requires a bit of work, but you're going to run into that with any
database system where the database is being accessed across multiple processes, and there is caching.

There are multiple issues with your code which are likely leading to a confused Core Data state. I can't be certain that they're causing your problem, but at the moment things are messed up badly enough that trying to debug this specific error is getting ahead of things. These problems include:
Confusion about how you're sharing data between your app and the extension.
You can do this using iCloud, or you can do it by using an app group to share the persistent store directly. You appear to be attempting both, which is not just unnecessary but also likely to cause problems keeping the extension up to date.
If you use iCloud to share data, you do not need the app group, because both the app and the extension will get their data from iCloud. You don't share a local persistent store in this case, instead the data is transferred via iCloud.
If you use an app group to share the persistent store file, you have no need of iCloud. The app and the extension both access the same file, which is located in the group container. Each can both read and write it.
Conflicting iCloud setups. You're using different values for NSPersistentStoreUbiquitousContentNameKey in different places. Even assuming that iCloud is working properly, this is going to prevent you from sharing data. If the app and extension are going to share via iCloud, they need to access the same cloud store, but you seem to be directing them to use separate cloud data stores.
You're not actually using the merge policy you're aiming for. You're passing NSMergeByPropertyObjectTrumpMergePolicy as one of the options when adding the persistent store file, but this isn't actually a valid option there. I would have expected at least a console message about this, but if there isn't one then it means Core Data is just silently ignoring that key. You set a merge policy by setting the value of the mergePolicy attribute on your managed object context. With no merge policy, you're falling back on the default NSErrorMergePolicy.
Unusual, suspicious code when adding the persistent store. In most cases with Core Data you'd add the persistent store and then later on create one or more managed object contexts. You appear to be creating the context first and only later adding a persistent store. That's not necessarily wrong but it's very unusual. If I were working on this code, it'd be a red flag to look over the life cycle of the Core Data stack very carefully. Especially if, as your code comments indicate, you're not getting any data at all in some cases.
Again I'm not sure if the above is directly causing this specific error, but they're going to be causing problems of various types and it wouldn't be surprising if the resulting confused state leads to this error.

Related

NSFetchedResultsController finds wrong number of objects

I'm seeing a situation where a NSFetchRequest returns a different number of objects depending on whether it's executed directly through the NSManagedObjectContext or as part of building a NSFetchedResultsController.
Sample code:
- (void)setupResultsController {
NSError *error = nil;
NSManagedObjectContext *ctx = [[DataManager sharedInstance] mainObjectContext];
// Create a fetch request and execute it directly
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [Song entityInManagedObjectContext:ctx];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"section" ascending:YES];
NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSArray *sortDescriptors = #[sortDescriptor, nameDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSArray *debugResults = [ctx executeFetchRequest:fetchRequest error:&error];
NSLog(#"Count from context fetch: %lu", (unsigned long)debugResults.count);
// Use the request to populate a NSFetchedResultsController
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:ctx
sectionNameKeyPath:#"section"
cacheName:#"Detail"];
[aFetchedResultsController performFetch:&error];
NSLog(#"Count from results controller fetch: %lu", (unsigned long)[[aFetchedResultsController fetchedObjects] count]);
_songResultsController = aFetchedResultsController;
}
Executing the above results in log messages:
2020-01-10 11:05:07.892772-0500 asb7[12985:105052] Count from context fetch: 10
2020-01-10 11:05:07.893259-0500 asb7[12985:105052] Count from results controller fetch: 9
The difference between the two fetches is that the NSFetchedResultsController is missing the most recently added object. An extreme oddity about this is that, after running the application some seemingly random number of times, the counts start to agree and the new object is fetched.
Edit:
The results become consistent if I pass nil as the cache name or if I remove the second sort descriptor. Obviously these cause undesirable behavior changes but may be clues.
It seems that the NSFetchedResultsController is seeing a stale cache as being valid. Changing a sort descriptor invalidates the cache however updating the persistent store file should invalidate it but apparently does not in this case.
After a bit more experimenting, I have an explanation...if not a solution. Adding new objects does not change the modification date of my .sqlite file. It updates the .sqlite-shm and .sqlite-wal but I'll guess those aren't considered when judging whether to use the cache. Using touch from a terminal session makes the problem go away for the next launch.
(Xcode 10.1, macOS 10.13.6, deployment target 10.3, iOS 12.1 simulator and 10.3.2 device)
Another edit:
I've uploaded a zipped project directory that demonstrates the problem at https://github.com/PhilKMills/CacheTest
What I get is: first run, 3 records for both fetches; second run, 6 and 3. I see it as entirely possible that this depends on my particular software versions but I'm not in a position to upgrade at the moment. Other people's results would be most interesting.
Note: without a FRC delegate being assigned, the problem does not appear.
I suspected that the issue related to the use of the FRC cache, though I was uncertain why that might be. One workaround would therefore be to abandon using the FRC cache. However, that's not ideal.
After further experimentation by the OP, it seems the problem relates to the timestamp on the .sqlite file associated with the persistent store. By inference(*), if the FRC detects that the timestamp has changed, it realises that its cache might be out of date, and rebuilds it - thereby detecting the newly added objects. However, because CoreData by default uses SQLite's "WAL journal mode" (see here and here), database updates are written not to the .sqlite file, but instead to a separate .sqlite-wal file: the timestamp on the .sqlite file is consequently not changed, even though the database has been updated. The FRC continues to use its cache, unaware of the additional objects (or indeed other changes).
A second workaround is therefore to abandon using SQLite's WAL journal mode. This can be achieved by specifying the required journal mode when loading the persistent store, using
NSSQLitePragmasOption:#{#"journal_mode":#"DELETE"}
see here.
(*) In fact, this is documented here:
“the controller tests the cache to determine whether its contents are still valid. The controller compares the current entity name, entity version hash, sort descriptors, and section key-path with those stored in the cache, as well as the modification date of the cached information file and the persistent store file.”

Save part of Core Data into the cloud

Working on iOS 7, I have to debug an application using Core Data with several entities. First I was asking for adding iCloud (and not cloud kit) to save all the data. But then, the client realized he wanted to save only some entities but not all of them into the cloud.
Is it something possible ? Do I need to use several NSPersistentStoreCoordinator ? (the application already use several NSManagedObjectContext, one per entity). Or maybe I can do something when I receive the notification :
NSPersistentStoreDidImportUbiquitousContentChangesNotification
and manually perform the merge but I really don't know how.
Thanks for your help.
Thanks to Tom Harrington, I created 2 configurations: CloudConfiguration and LocalConfiguration and I add some entities in each (this link helps me too).
Then, I add persistent store in the coordinator:
// Configure persistentStoreCoordinator
NSError* error1 = nil;
NSString *cloudConfiguration = #"CloudConfiguration";
NSPersistentStore *store1 = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:#"CloudConfiguration"
URL:[self storeURLForConfiguration:cloudConfiguration]
options:#{ NSPersistentStoreUbiquitousContentNameKey : #"iCloudStore" }
error:&error1];
if (error1) {
NSLog(#"Error: %# \n Description : %# \nUser info : %#", error1, error1.description, error1.userInfo);
}
NSLog(#"*************** cloud store url ************** : %#", store1.URL);
NSError* error2 = nil;
NSString *localConfiguration = #"LocalConfiguration";
NSPersistentStore *localStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:localConfiguration
URL:[self storeURLForConfiguration:localConfiguration]
options:nil
error:&error2];
if (error2) {
NSLog(#"Error: %# \n Description : %# \nUser info : %#", error2, error2.description, error2.userInfo);
}
NSLog(#"*************** local store url ************** : %#", localStore.URL);
All of my entities goes in one store only (cloud or local). Entities in different store don't have any relationship and I have a single model.
So here I go, I start my app for the first time all seems to be well configured. But when I try on another device or on the same device after deleting the app, I have a crash, just after getting : Using local storage: 0.
Here is the crash log :
[_PFUbiquityRecordImportOperation main](734): CoreData: Ubiquity: Error importing transaction log: <PFUbiquityTransactionLog: 0x16ed7f50>
transactionLogLocation: <PFUbiquityLocation: 0x16ed7ee0>: /var/mobile/Library/Mobile Documents/6ULEJ9RYTQ~fr~company~iCloudTestApp/CoreData/iCloudStore/mobile~E722813A-96E8-4E11-8DDE-56FF3837DEBD/iCloudStore/EU31J4aJIvvEyVMcWWYs1qgVajMk4_4fQxw1oe_Q0i0=/4C6B58B3-6C8D-4393-9B1E-8E48C7352091.1.cdt
transactionNumber: 1, exception: Invalid parameter value (bad entity)
User Info: (null)
2014-12-02 12:35:34.837 iCloudTestApp[1421:3b0b] -[_PFUbiquityRecordsImporter discoverAndImportAllAvailableLogs:error:](727): CoreData: Ubiquity: Exception while scanning for logs to import: Invalid parameter value (bad entity)
userInfo: (null)
It sounds weird to me because it's happen before the merge. Of course, I remove all the datas in the cloud before testing with those two configurations. If you have any idea...
Not multiple persistent store coordinators, but multiple persistent store files. You can add multiple persistent stores to the same coordinator by calling addPersistentStoreWithType:configuration:URL:options:error: multiple times. You don't have to use the same options every time, so you can use iCloud options for one store file but leave them out for a different one.
But you need to be aware of a couple of things:
You can't create relationships between objects in different persistent store files. If that's a problem, look into fetched properties. They're properties that transparently fetch objects using a predicate that you provide. They work sort of like one-way relationships.
You need some way to tell Core Data which store file to use for new objects. There are a couple of ways to do this:
If some of your entities could go in either persistent store, you'll need to use [NSManagedObjectContext assignObject:toPersistentStore:] every time you create a new instance.
For entities that will always be in the same store file, look into "configurations" for your model file. This lets you create named subsets of your model that contain only some of the entities. Use the configuration name when you add the persistent store file. Then, all new instances of those entities will automatically go to the right file.
Additional, based on updated question:
If you already have iCloud data that you need to use, you can't just switch to using configurations. The existing iCloud transaction logs may contain references to entities that are not in your new iCloud-only configuration. When it tries to import that data, it will fail, and you'll get errors like the one you're seeing.
If this app is still in development, I'd say just delete all existing iCloud data and go with the configuration. If you need to keep the existing iCloud data, you must ensure that all entities in the current iCloud data are still available. That most likely means you'll have to do without configurations and instead assign objects to one store or the other in your code.

Magical Record, multiple configurations and Restkit

I am using Magical Record in a fairly large IOS project. I use configurations to separate a large seed database from user data. Since Magical Record doesn't support configurations, I deconstructed Magical Record's setupCoreDataStackWithAutoMigratingSqliteStoreNamed method and replaced it with the following:
+(void) RB_setupMultipleStores:(NSString *) seedStoreName userStore:(NSString *) userStoreName
/* change persistent store to one with multiple configurations. Assumes Magical Record is initialized to perform auto migration. */
{
NSError * error= nil;
[MagicalRecord cleanUp]; //Tear down Magical Record
NSManagedObjectModel * model = [NSManagedObjectModel MR_defaultManagedObjectModel];
NSURL *seedURL = [NSPersistentStore MR_urlForStoreName:[seedStoreName stringByAppendingString:#".sqlite"]];
NSPersistentStoreCoordinator * coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
nil];
NSPersistentStore * seedStore =[coordinator
addPersistentStoreWithType:NSSQLiteStoreType
configuration:#"Seed"
URL:seedURL
options:options
error:&error];
if (!seedStore || error)
{
NSLog(#"Error setting up seed store:%# for %#", [error localizedDescription], seedURL);
exit(-1);
}
NSURL *userURL = [NSURL URLForDocumentDirectoryWithAppendedPath:[userStoreName stringByAppendingString:#".sqlite"]];
NSPersistentStore * userStore = [coordinator
addPersistentStoreWithType:NSSQLiteStoreType
configuration:#"User"
URL:userURL
options:options
error:&error];
if (!userStore || error)
{
NSLog(#"Error setting up user store:%# for %#", [error localizedDescription], userURL);
exit (-1);
}
[NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];
//Bring back Magical Record with updated coordinator.
[NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator];
[[NSManagedObjectContext MR_defaultContext] setUndoManager:nil];
}
Now I will be adding Restkit to the mix. I'd need to share the object model and persistent store, and I'd rather use one set of contexts rather than have two different stacks.
I see five potential approaches:
Modify https://github.com/blakewatters/RKMagicalRecord to support multiple configurations. This looks trivial but it requires I use a category to surface some private methods, and the good MR developers recommend against explicitly setting MR default and root saving contexts.
Create the Magical Record contexts first, and then assign them to Restkit. Will this even work? Does it make sense at all?
Initialize Restkit and Magical Record from the same NSPersistentStoreCoordinator. Does this make sense?
Create two separate stacks with different but similar NSPersistentStoreCoordinators.
Create my own stack and contexts, and make all calls to Restkit and MR using those contexts.
Can anyone recommend any of these or any other approaches? Each requires significant effort to even test. I'm about to head down the #1 path.
Thanks...
Fundamentally, CoreData has ways to deal with this already. You can have multiple coordinators point to the same store, or whatever your scenario is. It's up to each framework to allow you to be used against a stack that framework itself did not create or setup.
MagicalRecord boils down to a collection of helper methods for fetching and saving. You don't need to use ANY of the setup methods for MagicalRecord to work its magic on your fetches. The setup methods are there to help you get going faster on new projects, as well as providing a single access point for a "default" contexts for use when you perform fetches on the main thread/queue. For all other use, use the explicit inContext: parameter every time. Using that parameter, you can use whatever MOC you want, everything will work. This is by design. MagicalRecord was never written to replace CoreData. It was written to make the simple tasks easier.
With that, you could just let RestKit deal with your entire CoreData stack and use MagicalRecord only for the convenience APIs for fetching and saving. This would save you having to do any of those solutions and just get back to tackling your app specific issues...

iOS Core Data data insert

I have an app which asynchronously downloads a JSON file and then it should insert those objects within Core Data for persistent storage. Regarding the insert, is it a good idea to do it from the main thread? What if there are thousands of objects? Should I do the inserts on a different thread? Could you provide me with some snippets regarding this matter? Regarding the fetching of the objects after I've saved them, should I also use a different thread?
My code for inserting into Core Data is:
- (void) insertObjects:(NSArray*)objects ofEntity:(NSString *)entityName
{
NSString *key;
NSManagedObject *managedObject;
NSError *error;
for(NSDictionary *dict in objects){
managedObject = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:_managedObjectContext];
for(key in dict){
[managedObject setValue:dict[key] forKey:key];
}
}
[_managedObjectContext save:&error];
}
PS: The objects are of the same entity. The project runs on iOS 7.0 or higher.
Since I can't comment yet..
What iOS Versions do you plan to support? If 5 and higher, this might help Concurrency stack
Summary of the link:
you create a context of private concurreny type to access your physical data
based on this you create a context of main concurreny type
on top of this you use private concurrency type stores again.
Don't forget so save in every store, otherwise, the data seems to be saved while the app is running, but after restart it is lost.
And yes, you want to do it an extra thread, since it would otherwise block the UI if there are to many items.

CoreData in new project

Hoping you can help.
I've got an iOS app that was built 3 years ago with CoreData. The opportunity arose to make some significant updates and it was deemed easier to simply start a new Xcode project while continuing to use the existing bundle identifier so that the app remained an actual update for iTune users.
My question is; does creating a new project in Xcode and manually creating a replication of the Model/Entity/Attributes from the first version prevent the data to be available in the new project?
I've got some quick code in the first version of the app that simply returns the number of records in the data (see below), but when the same code is used in the new project it returns nothing, as though there's no data in the app. iCloud was also used in the first version.
I thought that if I had the first version of the app installed, created some records, and then installed the new version, the data would still be available.
Have I misunderstood how migration works with CoreData, and am I better off getting the old project, refactoring for ARC and manually moving over the new code so that the original Entity is still used?
Any advice would be appreciated.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *entityName = #"MyObjects";
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"row_id"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)]];
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"MyObjects" withExtension:#"mom"];
NSManagedObjectModel *managedObject = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSString *iCloudEnabledAppID = #"com.xxxx.myobjects";
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObject];
NSString *dataFileName = #"MyObjects.sql";
NSString *iCloudDataDirectoryName = #"Data.nosync";
NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
NSString *iCloudData = [[[iCloud path]
stringByAppendingPathComponent:iCloudDataDirectoryName]
stringByAppendingPathComponent:dataFileName];
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:iCloudEnabledAppID forKey:NSPersistentStoreUbiquitousContentNameKey];
[coordinator lock];
[coordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[NSURL fileURLWithPath:iCloudData]
options:options
error:nil];
[coordinator unlock];
NSManagedObjectContext *moc = nil;
if (coordinator != nil) {
moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc setPersistentStoreCoordinator: coordinator];
}
NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:moc
sectionNameKeyPath:nil
cacheName:nil];
[fetchedResultsController performFetch:nil];
NSLog(#">>>>>> %#", [fetchedResultsController fetchedObjects]); // returns 2 records
First, I'm not sure why you tagged this with MagicalRecord. Your sample code is all raw core data.
Second, if I were you, I would take the existing model file from the old app, and make that the first version of the data model in the new app. You could recreate the data model with the attributes and entities, etc and eventually end up with the same version hashes, but you don't need to go through that trouble if you've already got the starting point. Just start with the existing data model and move forward. Xcode and Core Data do not tie data model files to Xcode projects, and you don't have any lock in that way. The Managed Object Model files are just text files like all other code in your app.
Third, iCloud setup requires far less code in iOS7. It's pretty simple as the Core Data team decided to take care of all the setup and fallback store busywork. I suggest looking at the "What's new in Core Data" talk from WWDC2013.
And finally, have you made sure that you have actually duplicated the model with the existing store? If you have a model that is not compatible with the store, your Core Data stack will not have a persistent store attached. That is, from the top level (your NSManagedObjectContext) it'll appear to be initialized, but the attached NSPersistentStoreCoordinator will not have any stores. With no store, no data will save, and no data will load. The Managed Object Model version MUST match the version information in the store file. You can check this yourself with a calls to:
-[NSPersistentStoreCoordinator metadataForPersistentStore:]
or
+[NSPersistentStoreCoordinator metadataForPersistentStoreOfType:URL:error:]
in combination with
-[NSManagedObjectModel isConfiguration:compatibleWithStoreMetadata:]
You also mention migrations. Unless you have more than one data model, you are not actually migrating your data. But when you do have versions to migrate, you will also need to set the migration options for lightweight migrations (auto migrations) to act when you attach a store to a coordinator. I suggest reading over the Apple Documentation on Versioning and Migration.

Resources