我正在使用 CNContacts 来获取iOS设备中的电话簿联系人。
当我手机中有少量联系人(例如50)时,联系人很容易被取出。
然而,当我有很多联系人(例如500-700)时,它会挂起/等待很长时间才能将这些联系人从iOS电话簿中提取到我的应用程序阵列中。
以前我使用https://github.com/Alterplay/APAddressBook这是以前的Apple框架的快速库,但现在我使用的是最新的Apple框架。
我提取联系人的代码是....
#pragma mark - Get All Contacts....
-(void)getAllContactsWithNewFrameworkOfApple {
NSMutableArray *_contactsArray = [[NSMutableArray alloc]init];
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
if (status == CNAuthorizationStatusDenied || status == CNAuthorizationStatusDenied) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"This app previously was refused permissions to contacts; Please go to settings and grant permission to this app so it can use contacts" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
// [self presentViewController:alert animated:TRUE completion:nil];
return;
}
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
// make sure the user granted us access
if (!granted) {
dispatch_async(dispatch_get_main_queue(), ^{
// user didn't grant access;
// so, again, tell user here why app needs permissions in order to do it's job;
// this is dispatched to the main queue because this request could be running on background thread
});
return;
}
NSError *fetchError;
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[CNContactIdentifierKey,CNContactGivenNameKey,CNContactFamilyNameKey,CNContactEmailAddressesKey,CNContactPhoneNumbersKey]];
BOOL success = [store enumerateContactsWithFetchRequest:request error:&fetchError usingBlock:^(CNContact *contact, BOOL *stop) {
[_contactsArray addObject:contact];
NSLog(@"I am %@", _contactsArray);
}];
if (!success) {
NSLog(@"error = %@", fetchError);
}else {
NSLog(@"End with Success %@", _contactsArray);
[self finalUsage:_contactsArray];
}
}];
}
我试图以20个批量获取联系人,每次重新加载表格。但是在这里它无法在调度线程中重新加载,或者只是崩溃。
如何改进此代码以快速获取联系人?
感谢。
答案 0 :(得分:2)
正如Toro所提到的,requestAccessForEntityType: completionHandler:
方法没有在主(UI)线程上运行。从documentation您可以看到它提到:
用户可以授予或拒绝访问联系人数据 每个应用程序的基础。通过呼叫请求访问联系人数据 requestAccessForEntityType:completionHandler:方法。这不会 在要求用户许可时阻止您的应用程序。 仅在第一次请求访问时才会提示用户;任何 后续CNContactStore调用将使用现有权限。 Ť的他 在任意队列上调用完成处理程序。建议 您在此完成中使用CNContactStore实例方法 处理程序而不是UI主线程。此方法是可选的 CNContactStore用于后台线程。如果这种方法不是 使用时,CNContactStore可能会在用户访问时阻止您的应用程序 要求访问权限。
因此,您要在UI中执行任何更新,您必须在主线程上执行此操作。
dispatch_async(dispatch_get_main_queue(), ^{
//Update UI on the Main thread, like reloading a UITableView
});