Database preload in iOS 7

In the past, I released my application with a pre-installed database, so the user did not need to update it the first time it started. There was some code that I found in another SO question (sorry, I no longer have a link) that I added to my App Delegate persistentStoreCoordinator method:

 - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"db.sqlite"]; if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) { NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"db" ofType:@"sqlite"]]; NSError* err = nil; if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:&err]) { NSLog (@"Error - Could not preload database."); } } //... more code generated from the template here } 

When I try to do this in iOS 7, I get no errors, but the database is empty (even if the database in my mainBundle has all the information I expect). I noticed that there are more database files in the applicationDocumentsDirectory (.sqlite-shm file and .sqlite-wal file). Do I need to do something with these files? Or is it already impossible to have a preloaded database ship with the application?

EDIT: I tried adding code to copy the new .sqlite-shm and .sqlite-wal files, but that doesn't help.

+6
source share
2 answers

The basic data has changed a bit in iOS 7, mainly how the save is performed.

The Ahead Logging (wal) entry was introduced to improve performance, and therefore also for the sqlite WAL file.

You can tell your application to use the old log mode:

You can specify the log mode by adding NSSQLitePragmasOption to the parameters when calling addPersistentStoreWithType: Configuration: URL: options: error. For instance. in set the previous default DELETE mode:

 NSDictionary *options = @{ NSSQLitePragmasOption : @{@"journal_mode" : @"DELETE"} }; 

A source

I'm not sure if this will fix your problem, but this is a big thing that has changed with Core Data in iOS 7

If you want to know more about WAL, I suggest watching the WWDC # 207 session, β€œWhat's New in Master Data and iCloud”

+5
source

I also copied the .sqlite-shm and .sqlite-wal files, and this worked:

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *storePath = [documentsDirectory stringByAppendingPathComponent: @"emm_samples.sqlite"]; // Check if the sqlite store exists if (![[NSFileManager defaultManager] fileExistsAtPath:storePath]) { NSLog(@"File not found... copy from bundle"); // copy the sqlite files to the store location. NSString *bundleStore = [[NSBundle mainBundle] pathForResource:@"emm_samples" ofType:@"sqlite"]; [[NSFileManager defaultManager] copyItemAtPath:bundleStore toPath:storePath error:nil]; bundleStore = [[NSBundle mainBundle] pathForResource:@"emm_samples" ofType:@"sqlite-wal"]; storePath = [documentsDirectory stringByAppendingPathComponent: @"emm_samples.sqlite-wal"]; [[NSFileManager defaultManager] copyItemAtPath:bundleStore toPath:storePath error:nil]; bundleStore = [[NSBundle mainBundle] pathForResource:@"emm_samples" ofType:@"sqlite-shm"]; storePath = [documentsDirectory stringByAppendingPathComponent: @"emm_samples.sqlite-shm"]; [[NSFileManager defaultManager] copyItemAtPath:bundleStore toPath:storePath error:nil]; } else { NSLog(@"File exists"); } 

(Based on: Master Data Warehouse included in the Bundle app )

+5
source

Source: https://habr.com/ru/post/958089/


All Articles