CKDiscoverAllContactsOperation在iOS 10下停止工作

时间:2016-09-30 21:40:01

标签: ios ios10 cloudkit

我有一个支持iOS 8及更高版本的应用。我一直在使用CKDiscoverAllContactsOperation获取用户列表以进行共享。这个代码在iOS 8和iOS 9下工作得很好。但是在iOS 10下,完成块没有返回任何错误,但它也没有返回任何结果,即使有一些结果。

我还在控制台中注意到以下消息:

  

<错误>:获得了一个没有记录ID的用户发现进度回调:{}

这在操作开始和调用完成块之间出现。

以下是相关代码:

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];

我知道自iOS 10起已弃用CKDiscoverAllContactsOperation,并已被CKDiscoverAllUserIdentitiesOperation取代。但是,由于我的应用程序支持iOS 8,因此即使在iOS 10下我也不能使用相同的代码。事实上,我仍然使用其他几个已弃用的(从iOS 10开始) CloudKit类和这是唯一一个给我一个问题的类。

1 个答案:

答案 0 :(得分: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是此代码所使用的方法使用的完成块。