それで、それはついに起こりました。独立系 iPhone 開発者にとって最悪のシナリオが発生しました。アプリをアップグレードした後、何人かのユーザーが完全なデータ損失を報告しています。iCloud Core Data 同期が機能していません。私のユーザーは、このアプリを部分的に使用してビジネスを運営しています。これは本当に壊滅的な失敗です。
私が変更した唯一の iCloud 関連のことは、iCloud にキー値ストアを追加することでした。コア データ コードはまったく同じままで、同じモデル バージョン (移行なし) などです。
私のテストでは、すべてが美しく機能しました!しかし残念なことに、ユーザーは、更新されたアプリを開いたときにデータがもう存在しないと報告しました。
この理由は何でしょうか?
- 永続的なストア URL (ユビキタス URL) は変更されていないはずです。
- この問題は更新前に発生していたはずなので、マージの競合もほとんどありません。
おそらく、新しいどこにでもあるキー値ストアとの干渉でしょうか?
(私はこれをほとんど除外しました。)
以下に、管理対象オブジェクト モデルと永続ストアのコードを示します。問題を評価するために他に何か必要な場合はお知らせください。
- (NSManagedObjectContext *)managedObjectContext {
if (managedObjectContext_ != nil) {
return managedObjectContext_;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext_ = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[managedObjectContext_ performBlockAndWait:^{
[managedObjectContext_ setPersistentStoreCoordinator:coordinator];
if (useICloud) {
[managedObjectContext_ setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(mergeiCloud:)
name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
object:coordinator];
}
}];
}
return managedObjectContext_;
}
と
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator_ != nil) {
return persistentStoreCoordinator_;
}
NSMutableDictionary *options = [NSMutableDictionary dictionary];
NSURL *storeURL = [[self applicationDocumentsDirectory]
URLByAppendingPathComponent:@"SalesCalls.sqlite"];
[options setObject:[NSNumber numberWithBool:YES]
forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES]
forKey:NSInferMappingModelAutomaticallyOption];
if (useICloud) { // this is an internal flag set to YES
NSURL *iCloudURL = [[NSFileManager defaultManager]
URLForUbiquityContainerIdentifier:nil];
if (nil!=iCloudURL) {
NSString *cloudData = [[iCloudURL path]
stringByAppendingPathComponent:@"data"];
iCloudURL = [NSURL fileURLWithPath:cloudData];
[options setObject:@"at.topofmind.salesplus.store"
forKey:NSPersistentStoreUbiquitousContentNameKey];
[options setObject:iCloudURL
forKey:NSPersistentStoreUbiquitousContentURLKey];
NSURL *nosyncDir = [iCloudURL
URLByAppendingPathComponent:@"data.nosync"];
[[NSFileManager defaultManager] createDirectoryAtURL:nosyncDir
withIntermediateDirectories:YES
attributes:nil error:nil];
storeURL = [nosyncDir
URLByAppendingPathComponent:@"SalesCalls.sqlite"];
}
}
NSError *error = nil;
persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:[self managedObjectModel]];
if (![persistentStoreCoordinator_
addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil URL:storeURL options:options error:&error])
{
NSLog(@"Cannot create persistent store coordinator, %@, %@",
error, [error userInfo]);
abort();
}
return persistentStoreCoordinator_;
}
コメント、意見、勝手な推測など (そしてもちろん解決策も!) は大歓迎です。
アップデート:
私の顧客の 1 人がすべてのデータを失い、すべてを再インストールしてリセットした後 (デバイスの再起動など)、iCloud と同期できなくなりました。シンボルは単に設定に表示されません。