Итак, это, наконец, произошло. Наихудший сценарий для любого независимого разработчика iPhone произошел. Несколько пользователей сообщают о полной потере данных после обновления моего приложения. Синхронизация данных iCloud Core не работает. Мои пользователи частично используют это приложение для запуска своего бизнеса. Это поистине катастрофический провал.
Единственная связанная с 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_;
}
Комментарии, мнения, дикие догадки и т.д. (и, конечно же, решения!) приветствуются.
ОБНОВЛЕНИЕ:
Один из моих клиентов потерял все свои данные, и после переустановки и перезагрузки всего (перезагрузка устройства и т.д.) он не смог синхронизировать с iCloud. Символ просто не отображается в настройках.