在iOS 7中预加载数据库

在过去,我已经发布我的应用程序与预加载的数据库,所以用户不必在第一次运行更新。 有一些代码我发现在另一个问题上(对不起,没有链接了),我添加到我的应用代理的persistentStoreCoordinator方法:

 - (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 } 

当我尝试在iOS 7中这样做时,我没有得到任何错误,但数据库是空的(即使我的mainBundle的数据库有我期待的所有信息)。 我注意到在applicationDocumentsDirectory中有更多的数据库文件(一个.sqlite-shm文件和一个.sqlite-wal文件)。 我还需要对这些文件做些什么吗? 还是不能再有一个预装数据库的应用程序?

编辑:我试着添加代码来复制新的.sqlite-shm和.sqlite-wal文件,但是这并没有帮助。

核心数据在iOS 7中有所改变,主要是如何进行保存。

预先写入日志logging(wal)是为了提高性能而引入的,因此您可以看到WAL sqlite文件。

您可以告诉您的应用使用旧的“日记模式”:

在调用addPersistentStoreWithType时,您可以通过将NSSQLitePragmasOption添加到选项来指定日记模式:configuration:url:options:error。 例如,设置DELETE之前的默认模式:

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

资源

我不确定这是否会解决您的问题,但是iOS 7中的Core Data已经发生了很大的变化

如果您想了解更多关于WAL的信息,我build议您观看WWDC第207期会议“核心数据和iCloud新function”

我复制了.sqlite-shm和.sqlite-wal文件,它的工作原理如下:

 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"); } 

(基于: 应用程序包中包含的核心数据存储 )