CKDiscoverAllContactsOperation перестал работать под iOS 10

#ios #ios10 #cloudkit

#iOS #ios10 #cloudkit

Вопрос:

У меня есть приложение, которое поддерживает iOS 8 и выше. Я использовал CKDiscoverAllContactsOperation для получения списка пользователей для целей совместного использования. Этот код отлично работает под iOS 8 и iOS 9. Но в iOS 10 блок завершения не возвращает ошибок, но он также не возвращает результатов, даже если они есть.

Я также заметил следующее сообщение в консоли:

<Ошибка>: получен обратный вызов прогресса обнаружения пользователя без идентификатора записи: { }

Это появляется между моментом запуска операции и вызовом блока завершения.

Вот соответствующий код:

 CKDiscoverAllContactsOperation *op = [[CKDiscoverAllContactsOperation alloc] init];
op.discoverAllContactsCompletionBlock = ^(NSArray <CKDiscoveredUserInfo *> *userInfos, NSError *error) {
    if (error) {
        NSLog(@"Unable to get all app users: %@", error);
    } else {
        // process the found users
    }
};
[container addOperation:op];
  

Я знаю, что CKDiscoverAllContactsOperation это устарело с iOS 10 и было заменено на CKDiscoverAllUserIdentitiesOperation . Но поскольку мое приложение поддерживает возврат к iOS 8, не должно быть никаких причин, по которым я не могу использовать тот же код даже под iOS 10. На самом деле, я все еще использую несколько других устаревших (начиная с iOS 10) классов CloudKit, и это единственный, который вызывает у меня проблему.

Ответ №1:

После некоторых исследований кажется, что CKDiscoverAllContactsOperation это просто не работает должным образом под iOS 10. Вероятно, это ошибка в iOS 10, и ошибка будет отправлена в Apple. Но сейчас у меня есть пользователи, которые жалуются, и сейчас требуется обходной путь.

Самое простое решение — использовать новую операцию, когда она доступна, и использовать старую, когда ее нет.

Это привело к следующему базовому коду:

 if ([CKDiscoverAllUserIdentitiesOperation class]) {
    // Use the newer operation
    CKDiscoverAllUserIdentitiesOperation *op = [[CKDiscoverAllUserIdentitiesOperation alloc] init];
    NSMutableArray *users = [NSMutableArray array];
    op.userIdentityDiscoveredBlock = ^(CKUserIdentity *identity) {
        if (identity.hasiCloudAccount) {
            DatabaseShareUser *user = [[DatabaseShareUser alloc] init];
            user.recordId = identity.userRecordID;
            user.username = [NSPersonNameComponentsFormatter localizedStringFromPersonNameComponents:identity.nameComponents style:NSPersonNameComponentsFormatterStyleDefault options:0];
            [users addObject:user];
        }
    };
    op.discoverAllUserIdentitiesCompletionBlock = ^(NSError *error) {
        if (error) {
            NSLog(@"Unable to get app users: %@", error);

            completion(nil);
        } else {
            completion([users copy]);
        }
    };

    [container addOperation:op];
} else {
    // Use the old operation
    CKDiscoverAllContactsOperation *op = [[CKDiscoverAllContactsOperation alloc] init];
    op.discoverAllContactsCompletionBlock = ^(NSArray <CKDiscoveredUserInfo *> *userInfos, NSError *error) {
        if (error) {
            NSLog(@"Unable to get app users: %@", error);

            completion(nil);
        } else {
            NSMutableArray *res = [NSMutableArray array];
            for (CKDiscoveredUserInfo *userInfo in userInfos) {
                DatabaseShareUser *user = [[DatabaseShareUser alloc] init];
                user.recordId = userInfo.userRecordID;
                user.username = userInfo.displayName;
                [res addObject:user];
            }

            completion([res copy]);
        }
    };
    [container addOperation:op];
}
  

DatabaseShareUser это простой класс приложения, который хранит CKRecordID и отображает имя каждого пользователя.

completion это блок завершения, используемый методом, в котором находится этот код.

Комментарии:

1. Интересно, сообщила ли Apple о каком-либо прогрессе в исправлении этой ошибки. Спасибо.

2. @AnthonyC Не то, что я слышал. Поскольку существует разумный обходной путь, я не беспокоюсь об этом.