在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"); }
(基于: 应用程序包中包含的核心数据存储 )
- 如何浏览在我的iPhone上运行的应用程序中的核心数据?
- 如何在右侧队列上初始化ManagedObjectContext?
- cellForRowAtIndexPath不会在reloadRowsAtIndexPaths之后调用
- 如何编辑从iOS5中的妈妈加载的NSManagedObjectModel
- 核心数据 – 在多个线程之间共享NSManagedObjects
- 核心数据 – 在向xcddatamodel文件添加额外的属性之后,应用程序崩溃
- executeFetchRequest抛出致命错误:NSArray元素无法匹配Swift数组元素types
- 最有效的使用NSPredicate OR语句进行search的方法
- 核心数据:从多个实体或关系获取结果