在我的應用程序中,這是可用的Mac Appstore我有iCloud +核心數據爲小牛用戶集成。所以我使用最新的iCloud實現,它不像舊版本那麼麻煩......我想。iCloud核心數據輕量級遷移 - 實體消失
到目前爲止一切都很好,隨着應用程序的最新更新,我對數據庫做了一些小修改,只是向實體添加了一些新的屬性,併爲此創建了新的模型版本。
如果你開始更新的版本,所有的數據都在那裏,一切都很好。所有實體都在那裏。這是控制檯輸出:
storesDidChange: {
added = (
"<NSSQLCore: 0x100410d10> (URL: file:///Users/lars/Library/Containers/de.nulldesign.tyme.osx/Data/Library/Application%20Support/de.nulldesign.tyme/CoreDataUbiquitySupport/lars~053CB071-18DD-5ED8-B2F0-DD0341B523C7/iCloudStore/2B3578B9-3A28-492B-8C62-BFF7FE7076F3/store/TymeCloud.storedata)"
);
}
-[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](760): CoreData: Ubiquity: lars~053CB071-18DD-5ED8-B2F0-DD0341B523C7:iCloudStore
Using local storage: 1
片刻後,該進口商錯誤occures:
__76-[_PFUbiquityRecordsImporter batchDownloadTransactionLogsAtLocations:error:]_block_invoke(763): CoreData: Ubiquity: Librian returned a serious error for starting downloads Error Domain=LibrarianErrorDomain Code=1 "Der Vorgang konnte nicht abgeschlossen werden. (LibrarianErrorDomain-Fehler 1 - Unable to initiate download.)" UserInfo=0x600000271440 {NSDescription=Unable to initiate download., Item Errors={
"file:///Users/lars/Library/Mobile%20Documents/HR22V4547K~de~nulldesign~tyme/CoreData/iCloudStore/lars~053CB071-18DD-5ED8-B2F0-DD0341B523C7/iCloudStore/16Dv7DuLeM4RoFUBtAVIQokfWJRwGABtWC81frFMCp0=/7B142E0C-3C97-4344-B647-28330E5D7FE3.1.cdt" = "Error Domain=UBErrorDomain Code=0 \"Der Vorgang konnte nicht abgeschlossen werden. (UBErrorDomain-Fehler 0 - Error Domain=UBErrorDomain Code=0 \"The operation couldn\U2019t be completed. (UBErrorDomain error 0.)\")\"
…
UserInfo=0x600000271600 {NSDescription=Error Domain=UBErrorDomain Code=0 \"The operation couldn\U2019t be completed. (UBErrorDomain error 0.)\"}";
};
NSDescription = "Unable to initiate download.";
NSUnderlyingError = "Error Domain=UBErrorDomain Code=0 \"Der Vorgang konnte nicht abgeschlossen werden. (UBErrorDomain-Fehler 0.)\"";
}
然後,商店將改變事件觸發:
storesWillChange: {
NSPersistentStoreUbiquitousTransitionTypeKey = 4;
added = (
"<NSSQLCore: 0x100211490> (URL: file:///Users/lars/Library/Containers/de.nulldesign.tyme.osx/Data/Library/Application%20Support/de.nulldesign.tyme/CoreDataUbiquitySupport/lars~053CB071-18DD-5ED8-B2F0-DD0341B523C7/iCloudStore/2B3578B9-3A28-492B-8C62-BFF7FE7076F3/store/TymeCloud.storedata)"
);
removed = (
"<NSSQLCore: 0x100211490> (URL: file:///Users/lars/Library/Containers/de.nulldesign.tyme.osx/Data/Library/Application%20Support/de.nulldesign.tyme/CoreDataUbiquitySupport/lars~053CB071-18DD-5ED8-B2F0-DD0341B523C7/iCloudStore/2B3578B9-3A28-492B-8C62-BFF7FE7076F3/store/TymeCloud.storedata)"
);
}
,不少storesWillChange & storesDidChange after after:
storesDidChange: {
removed = (
"<NSSQLCore: 0x100410d10> (URL: file:///Users/lars/Library/Containers/de.nulldesign.tyme.osx/Data/Library/Application%20Support/de.nulldesign.tyme/CoreDataUbiquitySupport/lars~053CB071-18DD-5ED8-B2F0-DD0341B523C7/iCloudStore/2B3578B9-3A28-492B-8C62-BFF7FE7076F3/store/TymeCloud.storedata)"
);
}
-[PFUbiquitySetupAssistant tryToReplaceLocalStore:withStoreSideLoadedByImporter:](3250): CoreData: Ubiquity: <PFUbiquitySetupAssistant: 0x100411670>
Error refreshing peer range cache: (null)
storesDidChange: {
NSPersistentStoreUbiquitousTransitionTypeKey = 4;
added = (
"<NSSQLCore: 0x100410d10> (URL: file:///Users/lars/Library/Containers/de.nulldesign.tyme.osx/Data/Library/Application%20Support/de.nulldesign.tyme/CoreDataUbiquitySupport/lars~053CB071-18DD-5ED8-B2F0-DD0341B523C7/iCloudStore/2B3578B9-3A28-492B-8C62-BFF7FE7076F3/store/TymeCloud.storedata)"
);
removed = (
"<NSSQLCore: 0x100410d10> (URL: file:///Users/lars/Library/Containers/de.nulldesign.tyme.osx/Data/Library/Application%20Support/de.nulldesign.tyme/CoreDataUbiquitySupport/lars~053CB071-18DD-5ED8-B2F0-DD0341B523C7/iCloudStore/2B3578B9-3A28-492B-8C62-BFF7FE7076F3/store/TymeCloud.storedata)"
);
}
storesDidChange: {
added = (
"<NSSQLCore: 0x10020cdb0> (URL: file:///Users/lars/Library/Containers/de.nulldesign.tyme.osx/Data/Library/Application%20Support/de.nulldesign.tyme/CoreDataUbiquitySupport/lars~053CB071-18DD-5ED8-B2F0-DD0341B523C7/iCloudStore/2B3578B9-3A28-492B-8C62-BFF7FE7076F3/store/TymeCloud.storedata)"
);
}
-[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](760): CoreData: Ubiquity: lars~053CB071-18DD-5ED8-B2F0-DD0341B523C7:iCloudStore
Using local storage: 1
存儲發生更改後,所有實體都消失了,而這些未在此Mac上創建。其他人仍然存在。事件如果切換到雲存儲:
PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:使用本地存儲:0
只有升級所有其他的Mac對我的應用程序的最新版本後,缺少實體越來越再次同步。
該文檔說:對於與給定的NSPersistentStoreUbiquitousContentNameKey關聯的每個模型版本,都會獨立記錄和保存對商店的更改。如果模型版本匹配,則使用給定的NSPersistentStoreUbiquitousContentNameKey配置的持久性存儲只能與其他設備數據上的存儲同步數據。
如果遷移與NSPersistentStoreUbiquitousContentNameKey選項,以一種新的模式版本配置了持久的專賣店,這家店的從當前設備發起變化的歷史也將被遷移,然後用新的模型版本配置的任何其他設備合併
所以我想知道,如果這是在iCloud中進行輕量級遷移時的預期行爲。對於我的用戶而言,這絕不是預期的行爲,因爲他們的項目在他們升級了所有設備之前就消失了。
核心數據棧設置是非常簡單的:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if(_persistentStoreCoordinator)
{
return _persistentStoreCoordinator;
}
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if(_iCloudConnectionPossible)
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(storesWillChange:)
name:NSPersistentStoreCoordinatorStoresWillChangeNotification
object:_persistentStoreCoordinator];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(persistentStoreDidImportUbiquitousContentChanges:)
name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
object:_persistentStoreCoordinator];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(storesDidChange:)
name:NSPersistentStoreCoordinatorStoresDidChangeNotification
object:_persistentStoreCoordinator];
NSURL *localStoragePath = [self dataStorePathUseiCloud:_useCloudStorage];
NSError *error = nil;
[_persistentStoreCoordinator lock];
NSPersistentStore *persistentStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storagePath
options:[self storeOptionsUseiCloud:_useCloudStorage]
error:&error];
[_persistentStoreCoordinator unlock];
return _persistentStoreCoordinator;
}
- (NSDictionary *)storeOptionsUseiCloud:(BOOL)useiCloud
{
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
if(useiCloud)
{
[options setObject:@"iCloudStore" forKey:NSPersistentStoreUbiquitousContentNameKey];
}
return options;
}
- (NSManagedObjectContext *)managedObjectContext
{
if(_managedObjectContext)
{
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if(coordinator != nil)
{
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
moc.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
[moc performBlockAndWait:^
{
[moc setPersistentStoreCoordinator:coordinator];
}];
_managedObjectContext = moc;
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextWillSaveNotification:)
name:NSManagedObjectContextWillSaveNotification
object:_managedObjectContext];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(mergeChangesAfterDidSaveNotification:)
name:NSManagedObjectContextDidSaveNotification
object:_managedObjectContext];
return _managedObjectContext;
}
而且storesWill/DidChange處理:
- (void)storesWillChange:(NSNotification *)note
{
NSManagedObjectContext *moc = self.managedObjectContext;
[moc performBlockAndWait:^
{
NSError *error = nil;
if([moc hasChanges])
{
[moc save:&error];
}
[moc reset];
}];
}
- (void)storesDidChange:(NSNotification *)note
{
// refresh UI, ...
}
有沒有解決這個辦法嗎?這裏有什麼問題?
因此,能夠更改數據模型的唯一方法是將現有的從iCloud遷移到本地,然後遷移到新模型,殺死iCloud中的所有內容並將新模型推回。其他具有舊型號的設備在升級之前無法同步......可以工作。謝謝@Duncan;) – lars
將此添加到「可能的」解決方案中:執行自定義遷移,如下所述:http://www.objc.io/issue-4/core-data-migration.html,然後同步到iCloud。看起來我會沿着這條路線走下去。 – lars