Core data crashes the app [duplicate] - ios

I created a Core Data model in xcode 3.2 and after upgrading in Xcode 4.2, I then added a new entity of the NSManagedObject subclass (refer to the new entity).
First thing, it looks weird because it's not in the same group as the old one. Here is the picture on my xcode 4.2 (AlkitabDB is the one i created in xcode 3.2, EndeDB is the new one from current xcode version(4.2):
Second thing, I let it as it is, then I accessed the second entity (the new one) the same way as the first entity (the old one), and the error as titled appears.
Here is the error:
2012-01-16 21:13:38.496 iHuria[55953:207] Unresolved error Error Domain=NSCocoaErrorDomain Code=134100 "The operation couldn’t be completed. (Cocoa error 134100.)" UserInfo=0x8829cd0 {metadata=<CFBasicHash 0x882a370 [0x1839b38]>{type = immutable dict, count = 7,
entries =>
2 : <CFString 0x8829b90 [0x1839b38]>{contents = "NSStoreModelVersionIdentifiers"} = <CFArray 0x8829ff0 [0x1839b38]>{type = immutable, count = 0, values = ()}
4 : <CFString 0x8829bc0 [0x1839b38]>{contents = "NSPersistenceFrameworkVersion"} = <CFNumber 0x8829770 [0x1839b38]>{value = +320, type = kCFNumberSInt64Type}
6 : <CFString 0x8829bf0 [0x1839b38]>{contents = "NSStoreModelVersionHashes"} = <CFBasicHash 0x882a080 [0x1839b38]>{type = immutable dict, count = 1,
entries =>
0 : <CFString 0x882a010 [0x1839b38]>{contents = "AlkitabDB"} = <CFData 0x882a030 [0x1839b38]>{length = 32, capacity = 32, bytes = 0xd02ac5f8be6ab0b39add450aca202ac0 ... 3d45d462998d2ccd}
}
7 : <CFString 0x10e3aa8 [0x1839b38]>{contents = "NSStoreUUID"} = <CFString 0x8829e60 [0x1839b38]>{contents = "4F2EE7FF-463B-4055-BBED-8E603CDBDF59"}
8 : <CFString 0x10e3948 [0x1839b38]>{contents = "NSStoreType"} = <CFString 0x10e3958 [0x1839b38]>{contents = "SQLite"}
9 : <CFString 0x8829c40 [0x1839b38]>{contents = "NSStoreModelVersionHashesVersion"} = <CFNumber 0x6b1c7c0 [0x1839b38]>{value = +3, type = kCFNumberSInt32Type}
10 : <CFString 0x8829c70 [0x1839b38]>{contents = "_NSAutoVacuumLevel"} = <CFString 0x882a0c0 [0x1839b38]>{contents = "2"}
}
, reason=The model used to open the store is incompatible with the one used to create the store}, {
metadata = {
NSPersistenceFrameworkVersion = 320;
NSStoreModelVersionHashes = {
AlkitabDB = <d02ac5f8 be6ab0b3 9add450a ca202ac0 ebd1e860 cbb578c2 3d45d462 998d2ccd>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
);
NSStoreType = SQLite;
NSStoreUUID = "4F2EE7FF-463B-4055-BBED-8E603CDBDF59";
"_NSAutoVacuumLevel" = 2;
};
reason = "The model used to open the store is incompatible with the one used to create the store";
}
I looked for the solution before and discovered that I should remove the appliation from simulator and rerun the app, and it didn't work.
Does anyone know a solution for this issue?
Please help.

Deleting the app is sometimes not the case! Suggest, your app has already been published! You can't just add new entity to the data base and go ahead - you need to perform migration!
For those who doesn't want to dig into documentation and is searching for a quick fix:
Open your .xcdatamodeld file
click on Editor
select Add model version...
Add a new version of your model (the new group of datamodels added)
select the main file, open file inspector (right-hand panel)
and under Versioned core data model select your new version of data model for current data model
THAT'S NOT ALL ) You should perform so called "light migration".
Go to your AppDelegate and find where the persistentStoreCoordinator is being created
Find this line if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
Replace nil options with #{NSMigratePersistentStoresAutomaticallyOption:#YES, NSInferMappingModelAutomaticallyOption:#YES} (actually provided in the commented code in that method)
Here you go, have fun!
P.S. This only applies for lightweight migration. For your migration to qualify as a lightweight migration, your changes must be confined
to this narrow band:
Add or remove a property (attribute or relationship).
Make a nonoptional property optional.
Make an optional attribute nonoptional, as long as you provide a default value.
Add or remove an entity.
Rename a property.
Rename an entity.
For Swift 4
coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true])

Remove the app from the simulator and perform a clean on your project. That should clear those issues up. Make sure that you are not running in the debugger when you delete the app or else it won't actually delete it properly.
If you want to be sure its gone, check this directory Users/INSERT_YOUR_USER_HERE/Library/Application Support/iPhone Simulator/ for your app's folder, under the version you're running.
Note: This is for development only. For production, you need to implement some sort of migration. Google "Core Data Migration", with lightweight migration being the simplest.

Just add Options attribute while creating persistentStoreCoordinator in AppDelegate.m file for the core data method as below
OBJECTIVE-C
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil)
{
return _persistentStoreCoordinator;
}
NSLog(#"persistentStoreCoordinator___");
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"MyApp.sqlite"];
NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
NSLog(#"persistentStoreCoordinator___2");
return _persistentStoreCoordinator;
}
SWIFT
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
var failureReason = "There was an error creating or loading the application's saved data."
// MAIN LINE OF CODE TO ADD
let mOptions = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: mOptions)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "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 \(wrappedError), \(wrappedError.userInfo)")
abort()
}
return coordinator
}
It had solved my problem..

Answer : Remove the app from the Simulator , Perform a Clean and Re-Build your Project.
Note : Whenever you perform changes to the Core Data definition, Delete the app installed on the Physical Device or Simulator, Clean the Project and Re-Build again.

Yes. Once you delete app on physical device and rebuild it works.

For swift, in AppDelegate.swift find the line
try coordinator!.addPersistentStoreWithType(NSXMLStoreType, configuration: nil, URL: url, options: nil )
and replace it with
try coordinator!.addPersistentStoreWithType(NSXMLStoreType, configuration: nil, URL: url, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true])

I just spent several days fighting this error, as well as mergedModelFromBundles crashes, and getting the "Can't merge models with two different entities named *" error.
It turns out the root problem was that Xcode doesn't remove old resources from devices and I had old versions of my data model (.mom files) that were causing conflicts. This is why deleting the app fixed the problem on one of my devices.
After finding this blog post via another SO answer I made my app more tolerant of old models by changing this line which looks for ALL .mom files:
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
to this, which only looks in the Filters directory:
NSString *path = [[NSBundle mainBundle] pathForResource:#"Filters" ofType:#"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
I used recursivePathsForResourcesOfType from this so question: to help figure this out by logging all of the .mom files in the app:
NSArray *momPaths = [self recursivePathsForResourcesOfType:#"mom" inDirectory:[[NSBundle mainBundle] resourcePath]];
NSLog(#"All .mom files:%#",momPaths);
I also used iExplorer to look at the extraneous .mom files (I didn't try deleting them yet).
The method below was also helpful. It showed that an entity was in the merged model returned by [psc managedObjectModel] that didn't exist any more in any of my models or in the store itself. This was what let me to believe an old model was being cached on the device itself that clean building didn't remove. The method logs each entity that is the same, been changed, or added to, or removed from the model. (written with this SO answer as a starting point):
- (BOOL)comparePersistentStore:(NSPersistentStoreCoordinator *)psc withStoreURL: (NSURL *)storeURL {
NSError *error = nil;
// Get the entities & keys from the persistent store coordinator
NSManagedObjectModel *pscModel = [psc managedObjectModel];
NSDictionary *pscEntities = [pscModel entitiesByName];
NSSet *pscKeys = [NSSet setWithArray:[pscEntities allKeys]];
//NSLog(#"psc model:%#", pscModel);
//NSLog(#"psc keys:%#", pscKeys);
NSLog(#"psc contains %d entities", [pscModel.entities count]);
// Get the entity hashes from the storeURL
NSDictionary *storeMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType
URL:storeURL
error:&error];
NSDictionary *storeHashes = [storeMetadata objectForKey:#"NSStoreModelVersionHashes"];
//NSLog(#"store metadata:%#", sourceMetadata);
NSLog(#"store URL:%#", storeURL);
NSLog(#"store NSStoreUUID:%#", [storeMetadata objectForKey:#"NSStoreUUID"]);
NSLog(#"store NSStoreType:%#", [storeMetadata objectForKey:#"NSStoreType"]);
NSSet *storeKeys = [NSSet setWithArray:[storeHashes allKeys]];
// Determine store entities that were added, removed, and in common (to/with psc)
NSMutableSet *addedEntities = [NSMutableSet setWithSet:pscKeys];
NSMutableSet *removedEntities = [NSMutableSet setWithSet:storeKeys];
NSMutableSet *commonEntities = [NSMutableSet setWithSet:pscKeys];
NSMutableSet *changedEntities = [NSMutableSet new];
[addedEntities minusSet:storeKeys];
[removedEntities minusSet:pscKeys];
[commonEntities minusSet:removedEntities];
[commonEntities minusSet:addedEntities];
// Determine entities that have changed (with different hashes)
[commonEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSData *storeHash = [storeHashes objectForKey:key];
NSEntityDescription *pscDescrip = [pscEntities objectForKey:key];
if ( ! [pscDescrip.versionHash isEqualToData:storeHash]) {
if (storeHash != nil && pscDescrip.versionHash != nil) {
[changedEntities addObject:key];
}
}
}];
// Remove changed entities from common list
[commonEntities minusSet:changedEntities];
if ([commonEntities count] > 0) {
NSLog(#"Common entities:");
[commonEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSData *storeHash = [storeHashes objectForKey:key];
NSEntityDescription *pscDescrip = [pscEntities objectForKey:key];
NSLog(#"\t%#:\t%#", key, pscDescrip.versionHash);
}];
}
if ([changedEntities count] > 0) {
NSLog(#"Changed entities:");
[changedEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSData *storeHash = [storeHashes objectForKey:key];
NSEntityDescription *pscDescrip = [pscEntities objectForKey:key];
NSLog(#"\tpsc %#:\t%#", key, pscDescrip.versionHash);
NSLog(#"\tstore %#:\t%#", key, storeHash);
}];
}
if ([addedEntities count] > 0) {
NSLog(#"Added entities to psc model (not in store):");
[addedEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSEntityDescription *pscDescrip = [pscEntities objectForKey:key];
NSLog(#"\t%#:\t%#", key, pscDescrip.versionHash);
}];
}
if ([removedEntities count] > 0) {
NSLog(#"Removed entities from psc model (exist in store):");
[removedEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSData *storeHash = [storeHashes objectForKey:key];
NSLog(#"\t%#:\t%#", key, storeHash);
}];
}
BOOL pscCompatibile = [pscModel isConfiguration:nil compatibleWithStoreMetadata:storeMetadata];
NSLog(#"Migration needed? %#", pscCompatibile?#"no":#"yes");
return pscCompatibile;
}
usage: called before adding each store to NSPersistentStoreCoordinator :
[self comparePersistentStore:self.psc withStoreURL:self.iCloudStoreURL];
_iCloudStore = [self.psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.iCloudStoreURL
options:options
error:&localError];

Every time you making change to the Core Date definition, you should delete the apps installed on the physical device or simulator.

Stop app from running.
Delete app on simulator.
Product - > Clean
Build, run.

The simplest solution that worked for me in Swift 2.1, Xcode 7 is :
Delete the app from the Simulator ( Cmd + Shift + H to go to the Home Screen. Long Press the app, Click cross, just the usual way you delete an app from your phone)
Cmd + Shift + H again to stop the dancing of apps
Go back to your project and rerun
I had this issue while writing/reading from Core Data with 2 entities set up. Deleting the app and rerunning the program fixed the issue

I just deleted [Simulator App Folder]/Document/*.sqlite file after making changes in entities and it worked.
And of course, .sqlite file contains all stored data and structures which will be lost.

Please Delete a application from simulator and clean a code and run .its work fine .do it may be its help YOU.

If you are using Swift.
Follow the answer by #Stas and insert options, in place of nil, in your App Delegate:
let myOptions = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: myOptions, error: &error) == nil {

Try "Reset Content & Settings" in the simulator. Worked for me after deleting app and Clean build

I experienced the same issue with my app (not yet released in App Store).
Here's how I fixed it:
Run Clean (Cmd+Shift+K)
Restart iOS Simulator
iOS Simulator -> Reset Content and Settings (from navbar)
(3) was the step that finally got it to run properly. Hope this helps!

In my case, I had two persistent stores, one local store for user specific data, and one CoreData+CloudKit store for common data that syncs automatically with iCloud. Thus the data model has two configurations, and the entities are assigned to both configurations as required.
Due to a bug during development, I tried to store an entity that was no longer assigned to any configuration. So when the context was saved, CoreData realized the incompatibility, and crashed with this error.
Of course, deleting the app does not help in such a case. One has to ensure that only assigned entities are stored in a persistent store.

Although sometimes you can just remove the app from the device when changing schema in managed object model, in some scenarios this is not possible e.g. because you already published your app with an old schema.
If this is the case, you have to take care of migrating old data to the new schema:
Core Data Model Versioning and Data Migration

You'll need to migrate the Core Data model using migration. Any time you change the model, you make it incompatible without versioning. Strap yourself in, it's a bit of a hairy topic.
http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/CoreDataVersioning/Articles/Introduction.html

If you make changes to your Core Data model, you have to provide a migration policy that tells Core Data how to adopt existing persisted objects (that your users created with the currently released version) to the new model.
For some scenarios, Core Data is able to automatically infer the mapping from the old model to the new one. For more complex changes, you might have to implement some logic that performs the migration.
Details can be found in the Core Data Model Versioning and Data Migration Programming Guide.
Update
This answer here on Stack Overflow covers the basics of Core Data's lightweight migration and also has some code to get you started.

First, the only things that should be in the xcdatamodeld bundle are xcdatamodel files. Your subclasses should NOT be in the xcdatamodeld. Move those out of there. There is a fair chance they are confusing the compiler.
Second, the error indicates that Core Data cannot find your model. Have you created data and then touched the model? If so you are in an inconsistent state and need to fix that either by deleting the data (which Philippe suggested) or by rolling your changes of the model BACK.

This issue generally occurs due to incompatibility between the version on which DB has been created. General approach to this problem is to delete the app and reinstall it. But in your mentioned case the version of DB are completely different on Xcode 3.2 and 4.2. So better use same version of Xcode for DB.

I was getting the error but the reason I was getting the error was because of the following.
I originally had one Entity named "Entry" and had one row saved for that entity in the database. I then added another Entity named "Person" and after adding that went to build and got the error. So I solved the issue by deleting "Person" Entity and then building the app, deleted the row that was in "Entry" and then closed the application. I then deleted the app entirely off my phone and then did a rebuild and it worked fine. Not sure which step corrected the problem (the deletion of the row or the app), but hopefully if you're looking for a solution this will help. :)
Edit: Oh and if you worried about deleting your new Entity (in my case "Person") to build the app again remember you can get it back afterwards by using CMD+Z!

I had this problem - I first reset my simulator and then clean the project and rebuild. And then it works.

When you change core data, ( adding a field to table , removing field etc ), the sqlite file in applications document folder needs to be in sync with your schema.
This file is not overwritten by default, this file needs to be regenerated.
Follow these steps:
Go to the folder pointed by NSURL. (This path can be found in exception message generated by application before crashing.)
example : /Users//Library/Application Support/iPhone Simulator//Applications//Documents
remove or rename the sqlite file
Clean and Rerun the application
Rerunning application would generate a new sqlite file.
This will make sure that the schema and Xcode are in sync.

This may help some people but may not answer the question. In my case, the problem was solved because I forgot to add the model to the correct configuration. See the screenshot attached. All the models are added to the default configuration, but my application uses the private configuration. Drag and drop your model from the default configuration to the correct configuration.

iOS Simulator -> Reset Contents and Settings...
Worked for me
iOS Simulator -> Reset Contents and Settings... -> Reset
Works on iOS9 (xcode 7.1) as well

Related

Using CoreData to save and retrieve data from TextFields

Program Info
Hi! First question i've posted on Stackoverflow, so here it goes:
I am currently writing a program for used part inspection and need to be able to save the customer info using Core Data (or something else, if it is recommended). I just need to save it and then retrieve it to make a PDF.
Issues
-I am getting an error upon hitting the save button that says :
-I have no clue how to retrieve the data and convert it to PDF ( but thats a separate issue entirely)
Error
*2016-06-17 11:15:54.336 NewParts[6803:2846480] CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///var/mobile/Containers/Data/Application/1AAF2587-19C6-424F-BA3A-F37BBEE4AC71/Documents/SingleViewCoreData.sqlite options:(null) ... returned error Error Domain=NSCocoaErrorDomain Code=134100 "The managed object model version used to open the persistent store is incompatible with the one that was used to create the persistent store." UserInfo={metadata={
NSPersistenceFrameworkVersion = 641;
NSStoreModelVersionHashes = {
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "F4F8EB7F-B2EB-4D7F-A2A3-45FA91F8582E";
"_NSAutoVacuumLevel" = 2;
},*
Save Button Action
#IBAction func saveButton(sender: AnyObject)
{
var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext
var entity1 = NSEntityDescription.insertNewObjectForEntityForName("UsedInfo", inManagedObjectContext:context) as NSManagedObject
entity1.setValue("Test", forKey: "product")
do {
try context.save()
}
catch {
print("error")
}
}
Error that you've post actually have an explanation
Code=134100 The managed object model version used to open the
persistent store is incompatible with the one that was used to create
the persistent store
If your app is not published on the AppStore, you can simply remove app from the device (or simulator), Clean project and do Build&Run.
Whenever you make changes to Core Data definition you should delete the app and rebuild.
If your app is on AppStore, you should perform Core Data migration, you can find a lot of information on the Internet.
Apple Core Data Model Versioning and Data Migration, explains how to perform Automatic Lightweight Migration :
You request automatic lightweight migration using the options
dictionary you pass in
addPersistentStoreWithType:configuration:URL:options:error:, by
setting values corresponding to both the
NSMigratePersistentStoresAutomaticallyOption and the
NSInferMappingModelAutomaticallyOption keys to YES:
Which means that you can pass following options to your persistent coordinator :
let options = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]
coordinator.addPersistentStoreWithType(NSSQLiteStoreType,configuration: nil,URL : storeURL, options as! [NSObject : AnyObject])

Restkit 0.20 CoreData error "Can't find model for source store"

I am trying to configure RestKit with CoreData. I get and error with "Can't find model for source store". I was using the configurations from the Restkit RKTwitterCoreData example. I found some similar posts on stack overflow where people say to delete the database but I don't know how to do this, am running on my phone, not the simulator. I also tried to do a Product:Clean but same error.
2014-05-18 12:29:16.489 What my life could be[7006:60b] I restkit:RKLog.m:34 RestKit logging initialized...
2014-05-18 12:29:17.259 What my life could be[7006:60b] *** Assertion failure in -[AppDelegate application:didFinishLaunchingWithOptions:], /Users/Pro/Desktop/ios app/What my life could be/What my life could be/AppDelegate.m:161
2014-05-18 12:29:17.262 What my life could be[7006:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Failed to add persistent store with error: Error Domain=NSCocoaErrorDomain Code=134130 "The operation couldn’t be completed. (Cocoa error 134130.)" UserInfo=0x15d7fc40 {URL=file:///var/mobile/Applications/2E1DA997-E54E-4CE3-AC62-6552445D77CF/Documents/JustD.sqlite, metadata={
NSPersistenceFrameworkVersion = 479;
NSStoreModelVersionHashes = {
ActivityEntity = <fdd7d538 648131cf 2fe3b684 bd55169e 85a7cee4 cbec3080 94202e4c 26b97889>;
PriorityEntity = <74cd93d0 00ade70c ef4d0ea3 f177762d 7d342720 7aba6945 d83ee02d 96a2135c>;
UserDataEntity = <2ffd8aec e7c1dacc 23e14fdd 400b60c0 5a1cd9a8 07fe6138 4d0e5a30 8e0c6e28>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "B1BC3FFF-F727-49E4-A44F-5C5216C58226";
"_NSAutoVacuumLevel" = 2;}, reason=Can't find model for source store}'
*** First throw call stack:(0x2ec07e83 0x38f646c7 0x2ec07d55 0x2f5b00af 0xf37bb 0x313fcaad 0x313fc4f3 0x313f6b41 0x31391a07 0x31390cfd 0x313f6321 0x3387676d 0x33876357 0x2ebd2777 0x2ebd2713 0x2ebd0edf 0x2eb3b471 0x2eb3b253 0x313f55c3 0x313f0845 0xf3bc5 0x3945dab7)
libc++abi.dylib: terminating with uncaught exception of type NSException(lldb)
The part of code to config the store. I deleted the CoreData template default code, got error both ways. Note: I am not sure how the "importer importObjectsFromItemAtPath:...." works.
#ifdef RESTKIT_GENERATE_SEED_DB
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelInfo);
RKLogConfigureByName("RestKit/CoreData", RKLogLevelTrace);
NSError *error = nil;
BOOL success = RKEnsureDirectoryExistsAtPath(RKApplicationDataDirectory(), &error);
if (! success) {
RKLogError(#"Failed to create Application Data Directory at path '%#': %#", RKApplicationDataDirectory(), error);
}
NSString *seedStorePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:#"JustDid.sqlite"];
RKManagedObjectImporter *importer = [[RKManagedObjectImporter alloc] initWithManagedObjectModel:managedObjectModel storePath:seedStorePath];
[importer importObjectsFromItemAtPath:[[NSBundle mainBundle] pathForResource:#"activities" ofType:#"json"]
withMapping:activityMapping
keyPath:#"activity"
error:&error];
[importer importObjectsFromItemAtPath:[[NSBundle mainBundle] pathForResource:#"users" ofType:#"json"]
withMapping:userMapping
keyPath:#"user"
error:&error];
BOOL success = [importer finishImporting:&error];
if (success) {
[importer logSeedingInfo];
} else {
RKLogError(#"Failed to finish import and save seed database due to error: %#", error);
}
// Clear out the root view controller
[self.window setRootViewController:[UIViewController new]];
#else
/**
Complete Core Data stack initialization
*/
[managedObjectStore createPersistentStoreCoordinator];
NSString *storePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:#"JustD.sqlite"];
NSString *seedPath = [[NSBundle mainBundle] pathForResource:#"RKSeedDatabase" ofType:#"sqlite"];
NSError *error;
NSPersistentStore *persistentStore = [managedObjectStore addSQLitePersistentStoreAtPath:storePath fromSeedDatabaseAtPath:seedPath withConfiguration:nil options:nil error:&error];
NSAssert(persistentStore, #"Failed to add persistent store with error: %#", error);
// Create the managed object contexts
[managedObjectStore createManagedObjectContexts];
// Configure a managed object cache to ensure we do not create duplicate objects
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
#endif
It looks like you have changed the version of your core data model and not asked core data to try to migrate automatically or provided a migration explicitly. So, as core data loads it detects the version mismatch and aborts.
Initially, delete the app from your device and reinstall and everything should work again. You would need to do this each time you change the data model.
Obviously it isn't a good idea to go to the App Store like that so you should research auto migration and it's constraints and (if required) explicit migration.
To delete the database, just remove the sqlite file which should be at the address /var/mobile/Applications/2E1DA997-E54E-4CE3-AC62-6552445D77CF/Documents/JustD.sqlite
considering you logs
In a console:
rm /var/mobile/Applications/2E1DA997-E54E-4CE3-AC62-6552445D77CF/Documents/JustD.sqlite
Have you ensured your seed database is added to the Build Phase : Copy Bundle Resources?
I've just had the same problem for hours, and in the end it was as simple as that. Even though looking in the simulator-deployed app package, the seed sqlit file was there, but for some reason the managedObjectStore couldn't find it, but returned the “Can't find model for source store” error rather than, "Cannot find the seed data file" which would have been more helpful!

Core Data Migration Fail [duplicate]

This question already has answers here:
Fix Core Data Fail
(3 answers)
Closed 9 years ago.
My app was recently crashing on the app store because I did not migrate the data. So I was following this tutorial on Core Data Migration but it does not seem to be working:
1.I created a new model version for Core Data and set it to the current version...
2.I added the following code:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"Planner.sqlite"];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = #{
NSMigratePersistentStoresAutomaticallyOption : #YES,
NSInferMappingModelAutomaticallyOption : #YES
};
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
However when I run update the app on my iPhone it still crashes!
The changes I made was I added an entity.
Here is the crash log:
Unresolved error Error Domain=NSCocoaErrorDomain Code=134130 "The operation couldn’t be completed. (Cocoa error 134130.)" UserInfo=0x14fb4530 {URL=file:///var/mobile/Applications/E8C39F0E-027E-4D5B-8D7B-74D592290D46/Documents/Planner.sqlite, metadata={
NSPersistenceFrameworkVersion = 479;
NSStoreModelVersionHashes = {
Audio = <f195c962 11c85401 0457370e e1b037e1 24c4e393 dc38ca34 cda3bb57 a3e26f2c>;
Classes = <3b64e147 eb41441b 73bf051f ce094443 2017845b 2faba1c7 47848618 9fd9713b>;
Homework = <4295bdbf 75862060 c7f1a501 3b0934cd 9811e838 bc40c5d5 05f8d383 f315d1f8>;
Notes = <b7be1214 70a89b62 924df103 397a801a 96080505 be87b0e2 408ebf24 fdddb1a7>;
Picture = <451cd1a2 9daac38d 69165176 0cacb6c8 94d1e93d eca34239 61a15f35 573f7e40>;
Tests = <c10b5b25 228ebceb 6099b9af c830d203 bfca8e2b c9f46ee8 c0cd648e 9ad3e742>;
Video = <b95e2033 b45b5aaf 298fef31 e6e25685 2b842e4e f2b3d9d1 82359c5f db9c78eb>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "4327E676-759B-4733-A7ED-12309BD482EE";
"_NSAutoVacuumLevel" = 2;
}, reason=Can't find model for source store}, {
URL = "file:///var/mobile/Applications/E8C39F0E-027E-4D5B-8D7B-74D592290D46/Documents/Planner.sqlite";
metadata = {
NSPersistenceFrameworkVersion = 479;
NSStoreModelVersionHashes = {
Audio = <f195c962 11c85401 0457370e e1b037e1 24c4e393 dc38ca34 cda3bb57 a3e26f2c>;
Classes = <3b64e147 eb41441b 73bf051f ce094443 2017845b 2faba1c7 47848618 9fd9713b>;
Homework = <4295bdbf 75862060 c7f1a501 3b0934cd 9811e838 bc40c5d5 05f8d383 f315d1f8>;
Notes = <b7be1214 70a89b62 924df103 397a801a 96080505 be87b0e2 408ebf24 fdddb1a7>;
Picture = <451cd1a2 9daac38d 69165176 0cacb6c8 94d1e93d eca34239 61a15f35 573f7e40>;
Tests = <c10b5b25 228ebceb 6099b9af c830d203 bfca8e2b c9f46ee8 c0cd648e 9ad3e742>;
Video = <b95e2033 b45b5aaf 298fef31 e6e25685 2b842e4e f2b3d9d1 82359c5f db9c78eb>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
""
);
NSStoreType = SQLite;
NSStoreUUID = "4327E676-759B-4733-A7ED-12309BD482EE";
"_NSAutoVacuumLevel" = 2;
};
reason = "Can't find model for source store";
}
I already set the current model version.
Any help will be appreciated.
Thank you in advance,
Abdullah Shafique
According to #Scott I have to undo all the changes to my source and only change the destination
Can someone please explain the?
Try using this code to check the model versions and output the metadata
/*! The method checks the Core Data file version is compatible with the App's model version
and then pushes the main menu view onto the navigation stack. If not compatible it displays a
message to the user.
#param file The file URL for the Core Data Store. With UIManagedDocument you have to get the
actual store file URL, you can't just use the UIManagedDocument file URL.
*/
-(voidcheckCoreDataFileVersion:(NSURL*)file
{
if ([self checkVersion:file]) {
// file version is compatible so continue (add code to push the menu view)
} else {
// file version is NOT compatible
_fileOpenErrorAlert = [[UIAlertView alloc] initWithTitle:#"Unable to open Document" message:#"Please check that you have the correct application version installed" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[_fileOpenErrorAlert show];
}
return;
}
/*! Checks the Core Data files models version against the apps model version to see if they
are compatible. This will return YES if a lightweight migration can be performed and NO if NOT.
#param fileURL The file URL for the Core Data Store. With UIManagedDocument you have to get the
actual store file URL, you can't just use the UIManagedDocument file URL.
#return Returns YES if they are compatible and NO if not.
*/
- (bool)checkVersion:(NSURL*)fileURL {
NSManagedObjectModel *model = [self managedObjectModel];
NSLog(#" app model entity version hashes are %#", [model entityVersionHashesByName]);
NSError *error;
NSDictionary *metaData = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:fileURL error:&error];
if (!metaData) {
NSLog(#“ problem getting metaData");
NSLog(#“ - error is %#, %#", error, error.userInfo);
return NO;
}
bool result = [model isConfiguration:nil compatibleWithStoreMetadata:metaData];
if (!result) {
NSLog(#“ file is not compatible!");
NSLog(#“ metadata is %#", metaData);
}
return result;
}
The error says:
"Can't find model for source store";
It looks like you also modified previous model and hashes were regenerated. And they do not match, and because of that model for source store can not be found.
When you add a new Core Data model version XCode creates another model and you are prompted to provide a Model name for the new version. So now you should have two models in the XCode project. Once you have created the new version you then need to select it and set it to be the current version to be used by the application. You keep the old version of the model in the project.
In order for Core Data to open your existing files it needs the old version of the model (model for source store). It will then perform a migration by moving the data to the new schema (or model).
So the error above indicates that you have inadvertently made changes to the original version of the model (perhaps in addition to changes to the new version). However Core Data is unable to open the file without the correct model version so you need to restore a copy of the original core data model. If all you did was add a new entity to the new model then check whether this new entity has inadvertently been added to the old model and if so simply delete it from the old version of the model.

MagicalRecord: multiple databases

I have an app that uses MagicalRecord, and I'm pre-populating the database with a large amount of data that is used for reference. Within that same data model, I have user-definable information pertaining to things the user may do in the app.
The app was rejected because the pre-populated data is supposed to be marked as "do not backup". So, I'd like to have that data in a separate datastore so that I can keep the user data as backupable.
Is there a way to have two separate datastores using MagicalRecord?
I think it's possible, but not too easy though.
As you know, to work with more than one database, you should bring some changes to your PersistentStoreCoordinator, so it will have two PersistentStores. After this, you Core Data stack would look like this:
The other way is two make two separate PersistentStoreCoordinators, each carrying one store.
In Magical Record, there are several class methods for adding stores in
NSPersistentStoreCoordinator+MagicalRecord.h.
(NSPersistentStore *) MR_addInMemoryStore;
(NSPersistentStore *) MR_addAutoMigratingSqliteStoreNamed:(NSString *) storeFileName;
(NSPersistentStore *) MR_addSqliteStoreNamed:(id)storeFileName withOptions:(__autoreleasing NSDictionary *)options;
I think, that this is the place where you could do the thing you want.
Also i should mention, that the whole proccess of setting up the stack goes in MagicalRecord+Setup.h
+ (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName
So you can add your Stores and Coordinators there.
I've never managed it by myself, that was just a brief investigation of a possible solution.
I was able to solve this issue using configurations. Since Magical Record always sends null for the configuration parameter, I broke apart setupCoreDataStackWithAutoMigratingSqliteStoreNamed and replaced it with a method that supports multiple configurations.
Because Magical Record does a good job of handling auto migrations, I first call setupCoreDataStackWithAutoMigratingSqliteStoreNamed, followed by cleanup, and then I supply my replacement code.
I have one object model with my seed data objects assigned the the "Seed" configuration and user objects assigned to the "User" configuration. Magical Record has already been initialized so it could auto migrate if necessary.
+(void) RB_setupMultipleStores:(NSString *) seedStoreName userStore:(NSString *) userStoreName
/* change persistent store to one with multiple configurations. Assumes Magical Record is initialized. */
{
NSError * error= nil;
[MagicalRecord cleanUp];
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 = [NSPersistentStore MR_urlForStoreName:[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];
[NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator];
}
Also, MR 3.0 has concurrent stacks which may solve the problem once it is done.
Keeping data for different Core Data entities in different store files is well supported and fairly straightforward. However, MagicalRecrd doesn't provide any convenience methods for setting up your Core Data stack in this way. You simply have to allocate your stack manually, and tell MagicalRecord to use the NSPersistentStoreCoordinator you create. Here's how I did it in swift:
import Foundation
import CoreData
import MagicalRecord
class CoreDataSetup {
static func setupAutoMigratingStack(withContentConfigurationName contentConfigurationName: String, userConfirgurationNameName: String) {
MagicalRecord.cleanUp()
let managedObjectModel = NSManagedObjectModel.MR_defaultManagedObjectModel()
let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel!)
let contentURL = NSPersistentStore.MR_urlForStoreName(contentConfigurationName + ".sqlite")
let userURL = NSPersistentStore.MR_urlForStoreName(userConfirgurationNameName + ".sqlite")
let options = [
NSMigratePersistentStoresAutomaticallyOption : true,
NSInferMappingModelAutomaticallyOption: true,
NSSQLitePragmasOption: ["journal_mode": "DELETE"]
]
do {
try persistentStoreCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: contentConfigurationName, URL: contentURL, options: options)
try persistentStoreCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: userConfirgurationNameName, URL: userURL, options: options)
NSPersistentStoreCoordinator.MR_setDefaultStoreCoordinator(persistentStoreCoordinator)
NSManagedObjectContext.MR_initializeDefaultContextWithCoordinator(persistentStoreCoordinator)
} catch {
print("Error adding persistent store to coordinator: \(error) ")
}
}
}
Note that in my code I'm referring to your concept of the "seed" store as "content" and the user-definable store as "user".
To accomplish the second aspect of your question, configuring the content store to not be backed up, you simply have to play around with the URLs where you store each store, placing the content store in a non-backed up temporary directory, and copying it to that location up launch from your app bundle if it doesn't exist.

iOS Data Storage Guidelines Rejection

My app was rejected cause it must follow the iOS Data Storage Guidelines. I have already read some answer here on stackoverflow, and i have already read some blogs... I know my problem, at first application launch i copy 1 sqlite db and unzip some images in documents folder. The problem it's icloud that automaticcaly backup any files in documents directory. I don't need to use icloud in my app but my files must remain in document folder because they are the base data of my application and must be persit (cache folder or temp folder aren't correct solutions). So i've read about a flag that i can set file by file to forbid the backup :
[URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil];
I have also read that this method works only in ios higher than 5.0.1, in the other it will be simply ignored (i have setted my ios deployment target to 4.3)... If i use this method my app will be rejected again because the older ios devices backup aren't managed? If yes there is a cross-iosversion method to set the NSURLIsExcludedFromBackupKey?
EDIT
I'm sorry icloud isn't present in ios earlier 5.0 so i think that the problem regards only differences beetween version 5.0 and 5.0.1, I'm wrong?
I have passed all files that will stored in documents folder through this method.
Try this
-(BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
const char* filePath = [[URL path] fileSystemRepresentation];
const char* attrName = "com.apple.MobileBackup";
if (&NSURLIsExcludedFromBackupKey == nil) {
// iOS 5.0.1 and lower
u_int8_t attrValue = 1;
int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
return result == 0;
}
else {
// First try and remove the extended attribute if it is present
int result = getxattr(filePath, attrName, NULL, sizeof(u_int8_t), 0, 0);
if (result != -1) {
// The attribute exists, we need to remove it
int removeResult = removexattr(filePath, attrName, 0);
if (removeResult == 0) {
NSLog(#"Removed extended attribute on file %#", URL);
}
}
// Set the new key
NSError *error = nil;
[URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
return error == nil;
}
}
I've found this method here in Stack Overflow:
Use NSURLIsExcludedFromBackupKey without crashing on iOS 5.0
NOTE:
do not use
NSString *mediaDir = [NSString stringWithFormat:#"%#/Library/Caches/%#", NSHomeDirectory(), MEDIA_DIRECTORY];
since you are making assumptions about the name.
rather, use:
NSArray* lCachePaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString* lCacheDirectory = [lCachePaths objectAtIndex:0];
In my app I solved it by adding the files (images in my case) to the bundle,
and check in the method where I load the images if they exist in the document folder where the user generated data / images will be placed.
If it isn't there, I know it's one of my prepopulated images and I load it from the bundle.
For the sqlite file:
Not a really satisfying solution, but I create the data in code now, instead of a prepopulated sqlite file.
For media files, we store them in the Caches/ directory. During application startup, we check if they are there. Otherwise the images are either loaded from the bundle (in your case unzipped) or in our case re-downloaded from the Server.
The exact location is
NSString *mediaDir = [NSString stringWithFormat:#"%#/Library/Caches/%#", NSHomeDirectory(), MEDIA_DIRECTORY];
which is the place where you SHOULD store your temporary files. The files in the cache are generally persistent, much more so than in Temp, but can be deleted at some point.

Resources