Больше проблем с синхронизацией ядра iCloud

Итак, это, наконец, произошло. Наихудший сценарий для любого независимого разработчика 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. Символ просто не отображается в настройках.

Ответ 1

Я сталкивался с чем-то похожим с небольшим количеством применений (по вашему описанию я предположил, что у вас есть больше объема, чем у меня, что может быть причиной нескольких случаев)

В моем случае Apple, похоже, удалила без предварительного уведомления 20gb свободного места в icloud. Я заметил, что 2 пользователя, у которых пользователи с энергопотреблением потеряли новые данные из моего приложения (что было связано с историческим ценообразованием на акции), и другие, мы просто отлично загружаем один и тот же размер данных.

Я следил за этими 2, помогая им чистить вещи, чтобы позволить больше места в icloud и voila, после загрузки данных снова он работал нормально.