Crash When Saving On Device After Changing Datamodel - iphone

I've been hunting for a solution for the last four hours and I am posting in desperation. My app was working perfectly on the simulator, my iPhone, and my ipad until I added an attribute to one of my Data Models.
My iPhone application uses Core Data and iCloud. In the AppDelegate, I create the managedObjectModel by merging two models. Everything seems fine until I try to save the ManagedObjectContext. That's when it crashes with:
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This
NSPersistentStoreCoordinator has no persistent stores. It cannot
perform a save operation.'
This does not happen on the simulator.
I have tried:
Project->Clean Build Folder
Project->Clean
Deleting the app from my
device
Deleting the iCloud data from my iCloud back up
reboot computer
changed the ".momd" to ".mom" and back again (read about it in another question)
Thanks for the help.
EDIT to add code:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (__persistentStoreCoordinator != nil) {
return __persistentStoreCoordinator;
}
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
NSPersistentStoreCoordinator *psc = __persistentStoreCoordinator;
// TODO: Set up iCloud in another thread:
//dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *dataFileName = [NSString stringWithFormat:#"%#.sqlite", APP_TITLE_NO_SPACES];
NSString *iCloudDataDirectoryName = #"Data.nosync";
NSString *iCloudLogsDirectoryName = #"Logs";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *localStore = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:dataFileName];
NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
if (iCloud) {
NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];
if([fileManager fileExistsAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]] == NO) {
NSError *fileSystemError;
[fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]
withIntermediateDirectories:YES
attributes:nil
error:&fileSystemError];
if(fileSystemError != nil) {
NSLog(#"Error creating database directory %#", fileSystemError);
}
}
NSString *iCloudData = [[[iCloud path]
stringByAppendingPathComponent:iCloudDataDirectoryName]
stringByAppendingPathComponent:dataFileName];
NSLog(#"iCloudData = %#", iCloudData);
NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
CLOUD_CONTAINER_IDENTIFIER, NSPersistentStoreUbiquitousContentNameKey,
iCloudLogsPath, NSPersistentStoreUbiquitousContentURLKey, nil];
[psc lock];
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[NSURL fileURLWithPath:iCloudData]
options:options
error:nil];
[psc unlock];
} else {
NSLog(#"iCloud is NOT working - using a local store");
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[psc lock];
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:localStore
options:options
error:nil];
[psc unlock];
}
__persistentStoreCoordinator = psc;
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_ICLOUD_SOMETHING_CHANGED object:nil];
return __persistentStoreCoordinator;
}

Usually, it should okay after you deleted the program data. However, error indicates, that you do not have an inconsistency but simply no store at all. Assumption: you do not re-initiate it in case of a fault. Maybe, the following code can be useful:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator != nil) {
return __persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"myApp.sqlite"];
NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// Error, erase data
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];
NSLog(#"store cleaned");
__persistentStoreCoordinator = nil;
return [self persistentStoreCoordinator];
}
return __persistentStoreCoordinator;
}

Related

iOS Application freezing on first launch when iCloud is enabled

I enabled iCloud in my iOS app and on first launch of the app the app freezes for about 5 seconds when i press on any view in the app. I followed this tutorial to enable iCloud in my app and synchronize data using core data. I did not have this problem before adding iCloud synchronization. This only happens on first launch, not on other launches of the app. iCloud synchronization does occur. The problem is the app freezing.
Here is the code that manages the synchronization in my app delegate.
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
/*if (persistentStoreCoordinator == nil) {
NSURL *storeURL = [NSURL fileURLWithPath:[self dataStorePath]];
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
NSError *error;
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(#"Error adding persistent store %#, %#", error, [error userInfo]);
abort();
}
}
return persistentStoreCoordinator;*/
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
if ((persistentStoreCoordinator != nil)) {
return persistentStoreCoordinator;
}
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSPersistentStoreCoordinator *psc = persistentStoreCoordinator;
// Set up iCloud in another thread:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// ** Note: if you adapt this code for your own use, you MUST change this variable:
NSString *iCloudEnabledAppID = #"48S27G4A2S.com.maxned.iDownloadBlog";
// ** Note: if you adapt this code for your own use, you should change this variable:
NSString *dataFileName = #"DataStore.sqlite";
// ** Note: For basic usage you shouldn't need to change anything else
NSString *iCloudDataDirectoryName = #"Data.nosync";
NSString *iCloudLogsDirectoryName = #"Logs";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *localStore = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:dataFileName];
NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
if (iCloud)
{
//NSLog(#"iCloud is working");
NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];
/*NSLog(#"iCloudEnabledAppID = %#",iCloudEnabledAppID);
NSLog(#"dataFileName = %#", dataFileName);
NSLog(#"iCloudDataDirectoryName = %#", iCloudDataDirectoryName);
NSLog(#"iCloudLogsDirectoryName = %#", iCloudLogsDirectoryName);
NSLog(#"iCloud = %#", iCloud);
NSLog(#"iCloudLogsPath = %#", iCloudLogsPath);*/
if ([fileManager fileExistsAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]] == NO) {
NSError *fileSystemError;
[fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]
withIntermediateDirectories:YES
attributes:nil
error:&fileSystemError];
if (fileSystemError != nil) {
NSLog(#"Error creating database directory %#", fileSystemError);
}
}
NSString *iCloudData = [[[iCloud path]
stringByAppendingPathComponent:iCloudDataDirectoryName]
stringByAppendingPathComponent:dataFileName];
//NSLog(#"iCloudData = %#", iCloudData);
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[options setObject:iCloudEnabledAppID forKey:NSPersistentStoreUbiquitousContentNameKey];
[options setObject:iCloudLogsPath forKey:NSPersistentStoreUbiquitousContentURLKey];
[psc lock];
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[NSURL fileURLWithPath:iCloudData]
options:options
error:nil];
[psc unlock];
} else {
NSLog(#"iCloud is NOT working - using a local store");
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[psc lock];
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:localStore
options:options
error:nil];
[psc unlock];
}
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:#"SomethingChanged" object:self userInfo:nil];
});
});
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
return persistentStoreCoordinator;
}
/*- (NSManagedObjectContext *)managedObjectContext
{
if (managedObjectContext == nil) {
NSPersistentStoreCoordinator *coordinator = self.persistentStoreCoordinator;
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator:coordinator];
}
}
return managedObjectContext;
}*/
- (NSManagedObjectContext *)managedObjectContext
{
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc performBlockAndWait:^{
[moc setPersistentStoreCoordinator: coordinator];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(mergeChangesFrom_iCloud:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:coordinator];
}];
managedObjectContext = moc;
}
return managedObjectContext;
}
- (void)mergeChangesFrom_iCloud:(NSNotification *)notification
{
//NSLog(#"Merging in changes from iCloud...");
NSManagedObjectContext* moc = [self managedObjectContext];
[moc performBlock:^{
[moc mergeChangesFromContextDidSaveNotification:notification];
NSNotification* refreshNotification = [NSNotification notificationWithName:#"SomethingChanged"
object:self
userInfo:[notification userInfo]];
[[NSNotificationCenter defaultCenter] postNotification:refreshNotification];
}];
}
To fix this problem I changed the code to put it in another thread.
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *localStore = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:dataFileName];
NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
if (iCloud)
{
//NSLog(#"iCloud is working");
NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];
/*NSLog(#"iCloudEnabledAppID = %#",iCloudEnabledAppID);
NSLog(#"dataFileName = %#", dataFileName);
NSLog(#"iCloudDataDirectoryName = %#", iCloudDataDirectoryName);
NSLog(#"iCloudLogsDirectoryName = %#", iCloudLogsDirectoryName);
NSLog(#"iCloud = %#", iCloud);
NSLog(#"iCloudLogsPath = %#", iCloudLogsPath);*/
if ([fileManager fileExistsAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]] == NO) {
NSError *fileSystemError;
[fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]
withIntermediateDirectories:YES
attributes:nil
error:&fileSystemError];
if (fileSystemError != nil) {
NSLog(#"Error creating database directory %#", fileSystemError);
}
}
NSString *iCloudData = [[[iCloud path]
stringByAppendingPathComponent:iCloudDataDirectoryName]
stringByAppendingPathComponent:dataFileName];
//NSLog(#"iCloudData = %#", iCloudData);
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[options setObject:iCloudEnabledAppID forKey:NSPersistentStoreUbiquitousContentNameKey];
[options setObject:iCloudLogsPath forKey:NSPersistentStoreUbiquitousContentURLKey];
[psc lock];
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[NSURL fileURLWithPath:iCloudData]
options:options
error:nil];
[psc unlock];
} else {
NSLog(#"iCloud is NOT working - using a local store");
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[psc lock];
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:localStore
options:options
error:nil];
[psc unlock];
}
});
If this code is running on the main thread, that might be your problem.
From where is this code invoked on first (or any) launch?
Doing some searching myself, looks like this is actually expected behavior. As others have said App killed by SIGKILL when changing privacy settings and here: https://devforums.apple.com/message/715855
It is poorly documented, but working as designed. "On any of the permission changes iOS will terminate your app so that you aren't operating under the assumption of whatever the permissions were before. For example lets say the user gave you permissions for Contacts. Then they background your app and go and change that. You'd operate under the idea that you have permission when now you don't. So iOS just terminates the app."
"But it does not crash it is just forced to restart. You will get a SIGKILL message but no Crash log."

rename persistentstore coordinator URL

i have a (proably) simple to fix issue with my coredata persistent store.
i created it with:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (persistentStoreCoordinator != nil)
{
return persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"dummyURL.sqlite"];
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return persistentStoreCoordinator;
}
using the url dummyURL.sqlite
i did this on the first day working with the project, and have forgotten to rename it.. now all my current test devices (4) were in use for over 2 month, using the application, collecting a lot of data and storing it with a stupid url ^^
UPDATE i did some research on migration of persistent stores and wrote this function:
-(void)migrate{
NSPersistentStoreCoordinator *psc = [self.dataHandler.managedObjectContext persistentStoreCoordinator];
NSURL *oldURL = [psc URLForPersistentStore:[[psc persistentStores]objectAtIndex:0]];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSURL *newURL = [[appDelegate applicationDocumentsDirectory] URLByAppendingPathComponent:#"database.sqlite"];
NSError *error = nil;
NSPersistentStore *oldStore = [psc persistentStoreForURL:oldURL];
NSPersistentStore *newStore = [psc migratePersistentStore:sqliStoreOld
toURL:newURL
options:nil
withType:NSSQLiteStoreType
error:&error];
}
QUESTION 1 will this work or will i lose some data with that?
QUESTION 2 afterwards will i just have to change the appendString in my persistenstore function?
i managed to solve it myself using the migratePersistentStore function:
-(void)migrate{
NSPersistentStoreCoordinator *psc = [self.dataHandler.managedObjectContext persistentStoreCoordinator];
NSURL *oldURL = [psc URLForPersistentStore:[[psc persistentStores]objectAtIndex:0]];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSURL *newURL = [[appDelegate applicationDocumentsDirectory] URLByAppendingPathComponent:#"database.sqlite"];
NSError *error = nil;
NSPersistentStore *oldStore = [psc persistentStoreForURL:oldURL];
NSPersistentStore *newStore = [psc migratePersistentStore:sqliStoreOld
toURL:newURL
options:nil
withType:NSSQLiteStoreType
error:&error];
}
afterwards i just changed the appendURL to database.sqli in my appDelegate.
works like a charm :)
I would recommend creating a second persistent store with the new URL and adding a button somewhere that copies all of the data you have into the new one.
Make sure you test to make sure all your data is in the new persistent store before you remove the old one from the app.

Password protect/lock sqlite database from being opened outside the app with UIFileSharingEnabled?

I have UIFileSharingEnabled set in my iPhone app. I wanted to do this so the user could have access to the database.sqlite file managed by Core Data. This way, they could drag and drop it between their multiple iPhones/touchs/iPads and use it as sort of an poor-man's sync.
However, I don't want them opening the sqlite file and a) mucking around the database and b) reverse engineering my data model.
Does anyone know a way to password protect or lock out the database so that the user can't open it outside the app?
You can filter out the files that you make visible to the app, but not what is visible to iTunes FS.
When I added my iTunes File Sharing support to my app, I wrote code to silently move the DB file to a new directory that would not be visible to iTFS. The code below moves the sqlite DB file from the Documents directory to the Application Support directory which is not visible to iTFS.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
//
// Move th DB file to a different directory because of the file sharing
// feature.
//
NSString *oldDBFile = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: #"db.sqlite"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *newDBFile;
NSString *dbpath;
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSError *error;
NSURL *storeUrl;
BOOL dir;
dbpath = ([paths count] > 0 ? [paths objectAtIndex:0] : #"");
newDBFile = [dbpath stringByAppendingPathComponent:#"db.sqlite"];
if ([dbpath length] &&
[fileMgr fileExistsAtPath:dbpath
isDirectory:&dir] == NO) {
if ([fileMgr createDirectoryAtPath:dbpath
withIntermediateDirectories:YES
attributes:nil error:&error] == NO) {
NSLog(#"Cannot create %#: %# %#",
dbpath,
[error localizedDescription],
[error userInfo]);
}
}
if ([fileMgr fileExistsAtPath:oldDBFile]) {
if ([fileMgr moveItemAtPath:oldDBFile
toPath:newDBFile
error:&error] != YES) {
NSLog(#"Error moving DB: %#: %#", [error localizedDescription], [error userInfo]);
storeUrl = [NSURL fileURLWithPath:oldDBFile];
} else {
storeUrl = [NSURL fileURLWithPath:newDBFile];
}
} else {
storeUrl = [NSURL fileURLWithPath:newDBFile];
}
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, 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]);
// Handle the error.
}
return persistentStoreCoordinator;
}
Maybe you can use some ZIP or RAR library as they have support for password protection. Then zip the sqlite file when your app moves to background and unzip when comes to foreground.

Core data storage is repeated

I am trying to use Core Data in my application and I have been succesful in storing data into the entity.The data storage is done in the applicationDidFinishLaunchingWithOptions() method.But when I run the app again,it again gets saved.So how do I check if the data is already present or not??
Here is the code(Saving):
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *failedBankInfo = [NSEntityDescription
insertNewObjectForEntityForName:#"FailedBankInfo"
inManagedObjectContext:context];
[failedBankInfo setValue:#"Test Bank" forKey:#"name"];
[failedBankInfo setValue:#"Testville" forKey:#"city"];
[failedBankInfo setValue:#"Testland" forKey:#"state"];
NSError *error;
if (![context save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
(Retrieving):-
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"FailedBankInfo" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *info in fetchedObjects) {
NSLog(#"Name: %#", [info valueForKey:#"name"]);
}
`
Another thing I want to know that if I have thousands of records to store,then is there any other way to do it or can it be done through coding only???
Thanks
from what i understand you want to add all the data once only one time?
if so, move the inserting to the persistentStoreCoordinator method, and check if this is the first time the app lunches, by checking :
if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path] isDirectory:NULL]) {
firstRun = YES;
}
if it does then load the data. if not do nothing. this is how it look's at the end :
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator_ != nil) {
return persistentStoreCoordinator_;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"your_app.sqlite"];
BOOL firstRun = NO;
if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path] isDirectory:NULL]) {
firstRun = YES;
}
NSError *error = nil;
persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
if (firstRun) {
NSManagedObject *failedBankInfo = [NSEntityDescription
insertNewObjectForEntityForName:#"FailedBankInfo"
inManagedObjectContext:context];
[failedBankInfo setValue:#"Test Bank" forKey:#"name"];
[failedBankInfo setValue:#"Testville" forKey:#"city"];
[failedBankInfo setValue:#"Testland" forKey:#"state"];
NSError *error;
[moc save:&error];
}
return persistentStoreCoordinator_;
}
a.the way i do that is to create a plist with all the data.
b.import the plist as array of dictionaries (each dictionary is an entity".
c. set a function that iterates throw the array and adds the entities to the context.
something like that:
NSString *thePath = [[NSBundle mainBundle] pathForResource:#"recordsList" ofType:#"plist"];
NSArray *recordsArray = [[NSArray alloc] initWithContentsOfFile:thePath];
for (int i=0;i<[recordsArray count];i++)
{
//add the objects to the context
}
}
I have tried to simplify the answer, but you should know there are alot of thing you can do to better the process.
good luck

removeitematpath to remove Olddb.sqlite

I got this app that needs to be updated with a new database.
I want to remove the old one and replace it with the new.
This is the code I'm using:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: #"Newdb.sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
// If the expected store doesn't exist, copy the default store.
if (![fileManager fileExistsAtPath:storePath]) {
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:#"Newdb" ofType:#"sqlite"];
if (defaultStorePath) {
[fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
}
}
NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
NSError *error;
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
exit(-1); // Fail
}
return persistentStoreCoordinator;
}
I want my app to check at start-up if the Olddb.sqlite is there and if yes delete it!
here's the solution...
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [documentPaths objectAtIndex:0];
NSString *pathInDocuments = [docsDir stringByAppendingPathComponent:#"Olddb.sqlite"];
if (pathInDocuments) {
[fileManager removeItemAtPath:pathInDocuments error:NULL];
}