Reputation: 3534
I have created a framework project to include all the business logic of my application. So that, the core data model also moved to the framework project. Now I have a few XCTestCase classes to do unit testing for the manager and module classes in the framework. These classes have core data operation. So, during the unit testing, those classes refers to DBManager class. I am getting crash in this case, occurring at the creation of persistent model. At the same time when I used the same unit test cases in the main project, everything is working fine.One thing I mainly noted is that, the storeURL creating at the time of persistent creation is different while running main project and unit test cases in the framework. Following are the storeURL created. file:///Users/Gowtham/Library/Developer/CoreSimulator/Devices/F7DB4F9B-D323-4978-A816-B5363F26BE32/data/Containers/Data/Application/92F08534-F5AD-4B4B-B1A3-D3CEF17758C0/Documents/IHA.sqlite [Main project]
file:///Users/Gowtham/Library/Developer/CoreSimulator/Devices/F7DB4F9B-D323-4978-A816-B5363F26BE32/data/Documents/IHA.sqlite [Unit test cases in the framework project]
Following is the exception showing in the console.
Unresolved error Error Domain=YOUR_ERROR_DOMAIN Code=9999 "Failed to initialize the application's saved data" UserInfo={NSLocalizedDescription=Failed to initialize the application's saved data, NSUnderlyingError=0x7be93420 {Error Domain=NSCocoaErrorDomain Code=134100 "(null)" UserInfo={metadata={ NSPersistenceFrameworkVersion = 641; NSStoreModelVersionHashes = { UserDictionaryEntry = ; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = ( "" ); NSStoreType = SQLite; NSStoreUUID = "6C70A93B-39DD-4357-A0C2-0BDA5DF51E32"; "_NSAutoVacuumLevel" = 2; }, reason=The model used to open the store is incompatible with the one used to create the store}}, NSLocalizedFailureReason=There was an error creating or loading the application's saved data.}, { NSLocalizedDescription = "Failed to initialize the application's saved data"; NSLocalizedFailureReason = "There was an error creating or loading the application's saved data."; NSUnderlyingError = "Error Domain=NSCocoaErrorDomain Code=134100 \"(null)\" UserInfo={metadata={\n NSPersistenceFrameworkVersion = 641;\n NSStoreModelVersionHashes = {\n
UserDictionaryEntry = ;\n };\n
NSStoreModelVersionHashesVersion = 3;\n
NSStoreModelVersionIdentifiers = (\n \"\"\n );\n
NSStoreType = SQLite;\n NSStoreUUID = \"6C70A93B-39DD-4357-A0C2-0BDA5DF51E32\";\n \"_NSAutoVacuumLevel\" = 2;\n}, reason=The model used to open the store is incompatible with the one used to create the store}"; }
Can anyone give me suggestion for the proper way of writing unit test cases which communicate with core data in a Framework project?
The crash is happening in the following method of DatabaseManager class:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// The persistent store coordinator for the application. This implementation creates and returns 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:@"IHA.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;
}
When the app communicate with Framework project for DB operation, it's working fine. At the same time, when the XCTest Target in Framework project invokes DB operation, the crash is happening. Kindly request anyone to give a helpful answer.
Upvotes: 0
Views: 235
Reputation: 3534
Thanks for the suggestions given. Finally I found out the reason which is very simple. Even though, I have deleted the app from simulator, references of sqlite file created before in the following path was not cleared. Then I manually went to that path and deleted the old sqlite files generated. Then everything works fine. If anyone face the similar kind of issue, check the older sqlite file generated from the following path. There was a mismatch in the structure defined in older sqlite and xcdatamodel.
/Users/...username.../Library/Developer/CoreSimulator/Devices/F7DB4F9B-D323-4978-A816-B5363F26BE32/data/Documents/appname.sqlite
F7DB4F9B-D323-4978-A816-B5363F26BE32 is the folder which holds all the data related to the app.
Upvotes: 0
Reputation: 3573
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil)
{
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"IHA.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();
}
return _persistentStoreCoordinator;
}
Upvotes: 1