CKDiscoverAllContactsOperation 在 iOS 10 下停止工作
CKDiscoverAllContactsOperation stopped working under iOS 10
我有一个支持 iOS 8 及更高版本的应用程序。我一直在使用 CKDiscoverAllContactsOperation
来获取用户列表以供共享。此代码在 iOS 8 和 iOS 9 下工作正常。但是在 iOS 10 下,完成块 returns 没有错误,但它也 returns 没有结果,即使有一些。
我还在控制台中注意到以下消息:
<Error>: Got a user discovery progress callback with no record 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];
我知道 CKDiscoverAllContactsOperation
自 iOS 10 起已被弃用,并已被 CKDiscoverAllUserIdentitiesOperation
取代。但是由于我的应用程序支持回到 iOS 8,所以即使在 iOS 10 下我也没有任何理由不能使用相同的代码。事实上,我仍然使用其他几个已弃用的(如iOS 10) CloudKit 类 这是唯一给我一个问题的。
经过一些研究,似乎 CKDiscoverAllContactsOperation
根本无法正常工作,因为它应该在 iOS 10 下工作。这可能是 iOS 10 中的一个错误,将提交一个错误与苹果公司。但我现在有用户抱怨,现在需要解决方法。
最简单的解决方案是在可用时使用新操作,在不可用时使用旧操作。
这导致了以下基本代码:
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
是一个简单的应用程序 class,它存储每个用户的 CKRecordID
和显示名称。
completion
是此代码所在方法使用的完成块。
我有一个支持 iOS 8 及更高版本的应用程序。我一直在使用 CKDiscoverAllContactsOperation
来获取用户列表以供共享。此代码在 iOS 8 和 iOS 9 下工作正常。但是在 iOS 10 下,完成块 returns 没有错误,但它也 returns 没有结果,即使有一些。
我还在控制台中注意到以下消息:
<Error>: Got a user discovery progress callback with no record 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];
我知道 CKDiscoverAllContactsOperation
自 iOS 10 起已被弃用,并已被 CKDiscoverAllUserIdentitiesOperation
取代。但是由于我的应用程序支持回到 iOS 8,所以即使在 iOS 10 下我也没有任何理由不能使用相同的代码。事实上,我仍然使用其他几个已弃用的(如iOS 10) CloudKit 类 这是唯一给我一个问题的。
经过一些研究,似乎 CKDiscoverAllContactsOperation
根本无法正常工作,因为它应该在 iOS 10 下工作。这可能是 iOS 10 中的一个错误,将提交一个错误与苹果公司。但我现在有用户抱怨,现在需要解决方法。
最简单的解决方案是在可用时使用新操作,在不可用时使用旧操作。
这导致了以下基本代码:
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
是一个简单的应用程序 class,它存储每个用户的 CKRecordID
和显示名称。
completion
是此代码所在方法使用的完成块。