iCloud: проблема NSUbiquitousKeyValueStore

Я включаю iCloud в своем приложении, чтобы сохранить некоторые настройки. iCloud включен в разделе возможностей, и мой профиль обеспечения обновлен:

Мой код для сохранения и получения тестового примера выглядит следующим образом:

NSUbiquitousKeyValueStore *cloudStore = [NSUbiquitousKeyValueStore defaultStore];

if ([[cloudStore stringForKey:@"testString"] length] == 0) {
    NSLog(@"Nothing in iCloud - setting a value...");
    [cloudStore setString:@"I'm live in iCloud!" forKey:@"testString"];
    [cloudStore synchronize];
} else {
    NSString *result = [cloudStore stringForKey:@"testString"];
    NSLog(@"Found something in iCloud - here it is: %@", result);
}

Моя проблема заключается в том, что данные сохраняются только локально (например, NSUserDefaults). Когда я удаляю приложение на устройстве, сохраненные данные не восстанавливаются. Очевидно, что в другом устройстве данные также не могут быть восстановлены.

Первый раз данные сохраняются. Далее, если я открою приложение в другой раз, код else получит данные в порядке. Но когда я удаляю приложение de и запускаю снова, данные не сохраняются.

Кажется, что данные не сохраняются в iCloud, только локально.

Единственное "странное" в моем проекте - это то, что имя проекта не совпадает с именем пакета.

ОБНОВИТЬ:

Моя проблема только в iOs6. В iOs7 все отлично работает. Когда я отлаживаю свое приложение на устройстве с iOs 6 в разделе "отладочный навигатор", iCloud показывает:

Все шаги по настройке iCloud кажутся нормальными (для устройства с iOs7 работает нормально), и если я тестирую его с помощью следующего кода, работает нормально:

NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (ubiq) {
    NSLog(@"iCloud at %@", ubiq);

} else {
    NSLog(@"No iCloud access");
}

В чем дело?

Спасибо!

1 ответ

Решение

Вы пытаетесь получить данные из iCloud, когда они еще не загружены. Операция загрузки занимает некоторое время, и вы должны зарегистрироваться для NSUbiquitousKeyValueStoreDidChangeExternallyNotification, чтобы иметь возможность доступа к свежим данным из iCloud. Вот пример кода:

- (void) registerForiCloudNotificatons
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(handleChangesFromiCloud:)
                                                 name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification
                                               object:[NSUbiquitousKeyValueStore defaultStore]];
}

- (void) handleChangesFromiCloud: (NSNotification *) notification
{
    NSDictionary * userInfo = [notification userInfo];
    NSInteger reason = [[userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey] integerValue];
    // 4 reasons:
    switch (reason) {
        case NSUbiquitousKeyValueStoreServerChange:
            // Updated values
            break;
        case NSUbiquitousKeyValueStoreInitialSyncChange:
            // First launch
            break;
        case NSUbiquitousKeyValueStoreQuotaViolationChange:
            // No free space
            break;
        case NSUbiquitousKeyValueStoreAccountChange:
            // iCloud accound changed
            break;
        default:
            break;
    }

    NSArray * keys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey];
    for (NSString * key in keys)
    {
        NSLog(@"Value for key %@ changed", key);
    }
}
Другие вопросы по тегам