【问题标题】:iOS UIManagedDocument : can't open pre loaded persistent storeiOS UIManagedDocument:无法打开预加载的持久存储
【发布时间】:2013-01-18 15:40:38
【问题描述】:

我正在尝试在基于 UIManagedDocument 的应用程序中预加载持久存储以处理核心数据。

我尝试在应用 B 中使用的持久性商店是“生成”并填充的,这要归功于应用 A。 在应用程序 A 和 B 中,我使用 Justin Driscoll 的 UIManagedDocument 处理程序(available here,感谢 Driscoll 先生!)。在应用 A 中一切正常。

基于此线程中解释的技术:Pre-load core data database in iOS 5 with UIManagedDocument,我尝试将持久存储放在 B 的应用程序包中,并在 init 中根据需要(如果之前未完成)将此存储复制到文档文件夹中在实例化之前。

从包复制到文档一切正常(我尝试了不同的方法并通过 finder 和 nslog 检查了创建),但我就是无法打开“文档”。 应用程序不会崩溃,显示视图但表为空(我使用与应用程序 A 完全相同的代码,具有相同的 fetchedResultsController)。首先我认为复制的持久存储是空的,然后我意识到我无法正确打开文档/复制的持久存储) => 文档状态 = 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);
}

【问题讨论】:

    标签: ios core-data preload uimanageddocument nspersistentstore


    【解决方案1】:

    感谢一位同志,这是答案......如果有人搜索它:

    这是关于选择的!!

    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,这些选项不存在。问题中的代码在没有这些选项的情况下工作。
    • @vaichidrewar 很奇怪,实际上对我来说不是。我必须添加这些选项 NSIgnorePersistentStoreVersioningOption 才能使用迁移的 persistentStore(没有选项,应用程序总是拒绝打开商店)。选项在此处的 iOS 文档中有详细说明:developer.apple.com/library/ios/#Documentation/Cocoa/Reference/…
    • 我想我的意思是说 iphone ios 不需要这些。 Xcode 在开发 iPhone 应用程序时无法识别这些选项。但这些应该对 Mac 应用有效
    猜你喜欢
    • 2014-02-15
    • 2012-06-17
    • 2014-04-14
    • 1970-01-01
    • 2018-01-12
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多