iCloud NSUbiquitousKeyValueStore начальная задержка синхронизации / доступа - как справиться?

используя NSUbiquitousKeyValueStore для хранения некоторых настроек приложения. Моя логика такова: когда я сохраняю данные локально, я сохраняю их в NSUbiquitousKeyValueStore также в качестве резервной копии. Когда мне нужны настройки, я читаю локально и использую хранилище ключей iCloud только в том случае, если данные не найдены локально (например, после переустановки приложения). Если у пользователя есть несколько устройств, использующих один идентификатор icloud, он может записать настройки на одном устройстве и загрузить их на другое (я предупреждаю его о перезаписи).

У меня странная проблема. шаги:

Установил приложение и сохранил его данные в NSUbiquitousKeyValueStore. Убедился, что данные есть.Удалено приложение (при условии, что данные все еще сохраняются в iCloud).На всякий случай подождал несколько минут, затем установил и запустил приложение изнутри Xcode.Пытался прочитать ключ настроек, используя [[NSUbiquitousKeyValueStore defaultStore] dataForKey: @ "mykeyname»] - иногда этовсе в порядке, но иногда ключ не найден!Подождал 15 секунд, попробовал еще раз. Успех. Смущенный.

Похоже, что ios нужно некоторое время, чтобы локально сделать доступным хранилище значений ключей для моего приложения для dataForKey: call. Если я'Я написал такую систему (на самом деле я написал - некоторое время назад, в другой жизни), очевидно, должна быть задержка, прежде чем запрашивать и получать данные значения ключа. Так что я'Я хотел бы получить уведомление о том, что "мы закончили загрузку / синхронизацию хранилища значений ключей при первом запуске или что-то подобное.

Насколько я понимаю, я могу работать с NSUbiquitousKeyValueStore в основном потоке синхронно (что мне удобно). Но [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier: nil] возвращает действительный URL, а затем я получаю "ключ нет нашел ", Так что я могу'не надейся на это. Есть ли способ убедиться, что NSUbiquitousKeyValueStore работает и загружен? Это'Это особенно важно при медленном интернете.

ОБНОВИТЬ

Добавление [[NSUbiquitousKeyValueStore defaultStore] синхронизации] (как написано в Apple Docs) для инициализации и загрузки помогло немного. Тем не менее, есть много вопросов к iCloud.

Вчера я'мы успешно сохранили данные в хранилище ключей на телефоне 1 и восстановили на телефоне 2. Сегодня яудалил приложение на телефоне 2 и попытался восстановить данные. Но даже [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier: nil] возвратил действительный URL, и я вызвал [[NSUbiquitousKeyValueStore defaultStore] синхронизация] Я получаю ноль при вызове dataForKey: MY_DATA_KEY.

Когда я пытался восстановить данные из icloud на телефоне 1 (приложение все еще установлено), это успешно, но когда я переустанавливал на этом телефоне, приложение не восстанавливаетбольше не получается.

Временное решение:выключить iCloud->Документы &Данные - выключить и включить сеть - включить Документы иДанные", но также вы должны подождать несколько минут, и тогда это должно работать.

Итак, вопросы: 1. у вас есть такие проблемы с iCloud? 2. Есть ли способ узнать, данные недоступны или просто еще не загружены? 3. Есть ли известное?задержка" из iCloud? Я'я слышал около 7 секунд, но этоОчевидно, это не правда. 4. Кажется, что когда приложение не• Обновление данных iCloud без задержек происходит довольно быстро (в секундах), но при переустановке приложения icloud требуется несколько минут для актуализации хранилища значений ключей. Есть ли способ форсировать этот процесс?

Постскриптум Ниже для справки мой CloudHelper - довольно простой класс c ++ для записи / чтения двоичных данных в / из хранилища значений ключей iCloud. Это не компилируется, яЯ немного адаптировал его для SO, чтобы сделать его более понятным - удалил код, связанный с движком. Тем не менее, если вы удалите MySystem :: ... вызовы, это работает довольно хорошо. За исключением того, что я упоминал ранее.

class CloudHelper
{
public:
    static bool init();
    static void deInit();
    //save our data to iCloud with
    static int saveData(unsigned char* data, int from, int count);
    //get our data from iCloud
    static unsigned char * loadData(int *retsize, int * retint);
    //does iCloud work for us
    static bool isEnabled();
    //do we have our key in iCloud
    static int isAvailable();

    static const int RESULT_OK = 0;
    static const int RESULT_NO_CONNECTION = 1;
    static const int RESULT_NOT_FOUND = 2;
    static const int RESULT_SYNC_ERROR = 3;
private:
    static bool enabled;
    static NSURL *ubiq;
};



bool CloudHelper::enabled = false;

NSURL *CloudHelper::ubiq = NULL;

#define MY_DATA_KEY @"my_data_key"

int CloudHelper::saveData(unsigned char* data, int from, int count)
{
    if ([NSUbiquitousKeyValueStore defaultStore])
    {
        NSData *d = [[[NSData alloc] initWithBytes:(data + from) length:count] autorelease];
        [[NSUbiquitousKeyValueStore defaultStore] setData:d forKey: MY_DATA_KEY)];
        if ([[NSUbiquitousKeyValueStore defaultStore] synchronize] != TRUE)
            return RESULT_SYNC_ERROR;
        return RESULT_OK;
    }
    return RESULT_NO_CONNECTION;
}

unsigned char * CloudHelper::loadData(int *retsize, int * retint)
{
    if ([NSUbiquitousKeyValueStore defaultStore])
    {
        [[NSUbiquitousKeyValueStore defaultStore] synchronize];
        NSData *d = [[NSUbiquitousKeyValueStore defaultStore] dataForKey: MY_DATA_KEY];
        if (d != NULL)
        {
            if (retsize != NULL)
                *retsize = d.length;
            if (retint != NULL)
                *retint = RESULT_OK;
            return d.bytes;
        }
        else
        {
            if (retsize != NULL)
                *retsize = -1;
            if (retint != NULL)
                *retint = RESULT_NOT_FOUND;
        }
    }
    else
    {
        if (retsize != NULL)
            *retsize = -1;
        if (retint != NULL)
            *retint = RESULT_NO_CONNECTION;
    }
    return NULL;
}

int CloudHelper::isAvailable()
{
    int result = RESULT_NO_CONNECTION;

    if ([NSUbiquitousKeyValueStore defaultStore])
    {
        [[NSUbiquitousKeyValueStore defaultStore] synchronize];
        NSData *d = [[NSUbiquitousKeyValueStore defaultStore] dataForKey: MY_DATA_KEY];
        if (d != NULL)
            result = RESULT_OK;
        else
            result = RESULT_NOT_FOUND;
    }
    else
        result = RESULT_NO_CONNECTION;

    return result;
}

void CloudHelper::deInit()
{
    enabled = false;
    [ubiq release];
}

bool CloudHelper::init()
{
    enabled = false;
    NSURL *ubiq_ = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
    [[NSUbiquitousKeyValueStore defaultStore] synchronize];
    if (ubiq)
    {
        enabled = true;
        ubiq = [ubiq_ retain]; //save for further use
    }
    else
    {
        //is implemented elsewhere: this writes a local file with a counter, and if it is < REMINDER_COUNT allows us to show a warning to users
        bool allow = MySystem::isAllowToShowDialog();
        if (allow)
        {
            //determines network state with Apple's Reachability
            if (!MySystem::isNetworkAvailable())
                MySystem::showMessageBox(@"Network error"); //No network
            else
                MySystem::showMessageBox(@"You should log into your iCloud account to be able to backup your settings."); //No login
        }
    }
    return enabled;
}

ОБНОВЛЕНИЕ 2

Это'с 2016 года. Android стал iOSЗлой близнец, человечество обнаружило гравитационные волны, Хиггс получил свой нобелевский статус, Microsoft купила и убила Nokia, все видели Эмбер Херд и Дженнифер Лоуренс раздельно. Но iCloud по-прежнему так же глуп, как и был.

Наконец-то я'Я сделал свой собственный стек сетевых служб на нескольких VPS. Я отказался от использования сторонних сервисов, потому что большинство из них нестабильны и непредсказуемы. И все же мне нужен iCloud. Потому что другой умирающий от яблока ребенок не работает. SecKeyChain. Его служба умирает, когда начинается моя игра. Поэтому я решил хранить случайный UUID в облаке, чтобы различать пользователей (идентификатор устройства больше не существует) даже после переустановки. Но что может пойти не так? Все! Я'Мы потратили два дня, чтобы сделать это глупым для развертывания без ошибок, и теперь он время от времени теряет мои данные!

Спасибо Apple, спасибо, спасибо, спасибо! Ла-ла-ла! Гип-гип ура! (звуки цирковой музыки, переходящие в плач)

Ответы на вопрос(3)

Ваш ответ на вопрос