2015-11-09 132 views
3

我使用CNContacts去取我的iOS設備電話簿聯繫人。如何使用Apple聯繫人框架更快速地獲取iOS聯繫人?聯繫人列表很長?

當我在我的手機數量少接觸的(比如50)觸點容易獲取。

然而,當我有很多接觸的(比如500-700)它掛/等待很長時間才能從iOS的電話簿這些接觸讀取到我的應用程序的數組。

以前我用https://github.com/Alterplay/APAddressBook這對於之前的蘋果框架快速庫,但現在我使用的是蘋果最新的框架。

我的代碼來獲取聯繫人是....

#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批次提取通訊錄,每次重裝表。但是在這裏它不能在調度線程中重新加載,或者只是崩潰。

如何改善這種代碼快速獲取聯繫人?

謝謝。

+1

我認爲你可以得到一個子線程的接觸,但重裝表的時候,它應該在主線程中運行。它由於在** child **線程中重新加載表而崩潰。 – AechoLiu

回答

1

如託羅提到的,requestAccessForEntityType: completionHandler:方法沒有在主(UI)線程中運行。從documentation你可以看到它提到:

用戶可以授予或拒絕訪問聯繫人在 每個應用程序的數據。通過調用 requestAccessForEntityType:completionHandler:方法請求訪問聯繫人數據。當用戶被要求許可時,這不會 阻止您的應用程序。 只有在第一次請求訪問時纔會提示用戶;後續的任何CNContactStore調用將使用現有的權限。 T he 完成處理程序在任意隊列上被調用。建議使用 表示您在此完成 處理程序中使用CNContactStore實例方法,而不是UI主線程。當在後臺線程中使用CNContactStore時,此方法是可選的。如果使用此方法不是 ,則CNContactStore可能會阻止您的應用程序,同時請求訪問權限爲 。

因此,你想在UI中做的任何更新,你必須在主線程上做。

dispatch_async(dispatch_get_main_queue(), ^{ 
    //Update UI on the Main thread, like reloading a UITableView 
}); 
相關問題