我正在尝试在基于 UIManagedDocument 的应用程序中预加载持久存储以处理核心数据。
我尝试在应用程序 B 中使用的持久性存储区是“生成”并填充的,这要归功于应用程序 A。 在应用程序 A 和 B 中,我都使用 Justin Driscoll 的 UIManagedDocument 处理程序(available here,感谢 Driscoll 先生!)。一切都在应用程序 A 中完美运行。
基于此线程中解释的技术:Pre-load core data database in iOS 5 with UIManagedDocument ,我尝试将持久存储放在 B 的应用程序包中,并在需要时(如果之前没有做过)在实例化之前的 init 中将此存储复制到文档文件夹中。
从 bundle 复制到 documents 都可以(我尝试了不同的方法并通过 finder 和 nslog 检查了创建),但我就是无法打开“文档”。 应用程序不会崩溃,显示 View 但表为空(我使用与应用程序 A 完全相同的代码,具有相同的 fetchedResultsController)。首先我以为复制的持久存储是空的,然后我意识到我无法正确打开文档/复制的持久存储) => Document state = 5,意思是 UIDocumentStateClosed 和 UIDocumentStateSavingError 的错误(如果我正确解释它???)
(注意:我也尝试过直接从包中实例化并打开文档,但我遇到了同样的问题:doc state = 5)
所以... 与此文档打了三天状态= 5 并且不知道要修复什么
我想我放在应用程序 B 包中的文件有问题(目前我从 finder 拖放到 xcode 并选择了“为任何添加的文件夹创建文件夹引用”) 也许是关于某些选项、元数据、文件权限或...
知道要调查什么吗?
(我不认为它与以下代码有关,但好吧......) 这是我的初始化方式(基于 Justin Driscoll 处理程序。只有 custo 是:我检查文档文件夹中是否有商店包,如果没有,我根据包中的文件创建它)
- (id)init
{
self = [super init];
if (self) {
self.document = nil;
NSLog(@"--- INIT ---");
// On vérifie si il y a un dossier "My-Default-Document-As-Database" (notre persitent store) dans le dossier "Documents"
NSString *docDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *docFolderPath = [docDirectory stringByAppendingPathComponent:@"My-Default-Document-As-Database"];
if (![[NSFileManager defaultManager] fileExistsAtPath:docFolderPath]) {
NSError *error = nil;
NSLog(@"Pas de fichier trouvé à l'adresse docFolderPath, on va donc y créer notre persistent store");
// COPY FROM BUNDLE
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *DB = [docFolderPath stringByAppendingPathComponent:@"StoreContent"];
[fileManager createDirectoryAtPath:DB withIntermediateDirectories:YES attributes:nil error:&error];
NSLog(@"create directory error: %@",error);
DB = [DB stringByAppendingPathComponent:@"persistentStore"];
NSString *shippedDB = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"persistentStore"];
NSLog(@"%d",[fileManager fileExistsAtPath:shippedDB]);
[fileManager copyItemAtPath:shippedDB toPath:DB error:&error];
NSLog(@"Copy error %@",error);
}
NSLog(@"== My-Default-Document-As-Database OK DANS DOCUMENTS ==");
NSURL *myDbUrl = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
myDbUrl = [myDbUrl URLByAppendingPathComponent:@"My-Default-Document-As-Database/"];
self.document = [[UIManagedDocument alloc] initWithFileURL:myDbUrl];
NSLog(@"== initWithFileUrl ==");
// Set our document up for automatic migrations
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
self.document.persistentStoreOptions = options;
// Register for notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(objectsDidChange:)
name:NSManagedObjectContextObjectsDidChangeNotification
object:self.document.managedObjectContext];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:self.document.managedObjectContext];
}
return self;
}
只有我对 Driscoll 先生提供的 performWithDocument 代码所做的“修改”是一些 nslog,以查看发生了什么(文档状态在每次第一次打开尝试时从 1 变为 5,然后保持为 5...)
- (void)performWithDocument:(OnDocumentReady)onDocumentReady
{
NSLog(@"passage par performWithDoc");
void (^OnDocumentDidLoad)(BOOL) = ^(BOOL success) {
NSLog(@"FilePath Apres = %@",[self.document.fileURL path]);
NSLog(@"STATE === %d", self.document.documentState);
onDocumentReady(self.document);
};
NSLog(@"FilePath Avant = %@",[self.document.fileURL path]);
NSLog(@"STATE === %d", self.document.documentState);
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.document.fileURL path]]) {
[self.document saveToURL:self.document.fileURL
forSaveOperation:UIDocumentSaveForCreating
completionHandler:OnDocumentDidLoad];
NSLog(@"performWithDoc > fileexistAtPath nope => saveToURLForCreating");
NSLog(@"STATE === %d", self.document.documentState);
} else if (self.document.documentState == UIDocumentStateClosed) {
[self.document openWithCompletionHandler:OnDocumentDidLoad];
NSLog(@"performWithDoc > UIDocStateClosed => openWithCompletionHandler");
NSLog(@"STATE === %d", self.document.documentState);
} else if (self.document.documentState == UIDocumentStateNormal) {
OnDocumentDidLoad(YES);
NSLog(@"performWithDoc > docState = normal => docdidLoad(YES)");
}
NSLog(@"STATE === %d", self.document.documentState);
}
最佳答案
感谢同伴,这里是答案......如果有人搜索它:
这是关于选项的!!
将 NSIgnorePersistentStoreVersioningOption
添加到 init 中的 pesistenStore 选项。
关于以前的代码,你应该有这样的东西:
// Set our document up for automatic migrations
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSIgnorePersistentStoreVersioningOption,
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
self.document.persistentStoreOptions = options;
关于iOS UIManagedDocument : can't open pre loaded persistent store,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14402341/