2011-12-09 82 views
4

我的应用程序正在使用核心数据SQLite数据库。我想让我的用户可以使用iCloud在设备之间同步它 - 我想我可以使用UIManagedDocument。UIManagedDocument只能读取文件包的文档

我遵循Apple的文档对它进行了分类,并且在需要创建新的持久性存储文件时工作正常。然而,当我尝试用它来打开我的旧持久性存储文件,我得到以下异常抛出错误:

“UIManagedDocument只能读取那些文件包文件”

这是否意味着我需要将旧的持久存储迁移到由UIManagedDocument管理的新存储?如果是这样,我是否需要手动执行此操作(即,从旧商店一次读取每条记录并将其写入新的记录)?

在此先感谢!

回答

5

UIManagedDocument创建包(文件夹)而不是原子存储。该商店仍然在那里,但它被埋在包里。如果右键单击在模拟器的“文档”文件夹中创建的文件,您将能够看到结构。默认值是

mydocument.foo 
    -> StoreContent 
     -> persistentStore 

你需要做的是为您的应用程序文件类型的一个新的扩展因此,例如,如果你的数据库扩展为.myappdb,你需要创建项目中设置一个新的文档类型,这可能是.myappdbw什么。您可以从入口在您把手在mydocumenturl打开旧版文档而不是传递,为您的持久性存储统筹创建上面的目录结构点复制所有设置.myappdb

下一步。

NSURL *newurl = [[mydocumenturl URLByDeletingPathExtension] URLByAppendingPathExtension:@"myappdbw"]; 
NSURL *desturl = [newurl URLByAppendingPathComponent:@"StoreContent"]; 
[[NSFileManager defaultManager] createDirectoryAtURL:desturl withIntermediateDirectories:YES attributes:nil error:NULL]; 
NSURL *finalurl = [desturl URLByAppendingPathComponent:@"persistentStore"]; 

然后将原有数据库为您创建

[[NSFileManager defaultManager] moveItemAtURL:mydocumenturl toURL:finalurl error:NULL]; 

的文件夹系统,然后你可以通过捆绑网址UIManagedDocument

UIManagedDocument *doc = [[UIManagedDocument alloc] initWithFileURL:newurl]; 

,这将是非常有用的链接对于iCloud整合是

http://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-iCloudCoreData/_index.html

它的全部有点神秘,因为迄今为止承诺的示例代码中的大部分都未能出现,但另一方面它的推导起来相当简单。查看WWDC2011会议107,116和315获取更多提示。

但要注意的是,如果你要使用此方法迁移旧版文档DONT设置NSPersistentStoreUbiquitousContentNameKey你迁移,因为包当你改变点。上面的文档很好地描述了它。

1

感谢您的提示。我想我找到了一个更简单的解决方案。

我只是创建一个新的UIManagedDocument与我的旧的持久存储位置不同的文件名。

在我的子类UIManagedDocument,我重写configurePersistentStoreCoordinatorForURL方法,做好迁移一旦有:

- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)storeURL ofType:(NSString *)fileType modelConfiguration:(NSString *)configuration storeOptions:(NSDictionary *)storeOptions error:(NSError **)error 
{ 
    // If legacy store exists, copy it to the new location 
    NSFileManager* fileManager = [NSFileManager defaultManager]; 
    if ([fileManager fileExistsAtPath:legacyPersistentStoreURL.path]) 
    { 
     NSError* thisError = nil; 
     [fileManager copyItemAtURL:legacyPersistentStoreURL toURL:storeURL error:&thisError]; 
     [fileManager removeItemAtURL:legacyPersistentStoreURL error:&thisError]; 
    } 

    return [super configurePersistentStoreCoordinatorForURL:storeURL ofType:fileType modelConfiguration:configuration storeOptions:storeOptions error:error]; 
} 
+0

更好地使用'[文件管理replaceItemAtURL:storeURL withItemAtURL:legacyPersistentStoreURL backupItemName:无选项:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:零误差:thisError ];'而不是复制和删除,因为复制不会覆盖现有的文件 – Shmidt