2011-12-09 80 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