title: How to fetch iOS Contacts more quickly using Apple's Contacts framework having long list of contacts?
body: <p>I am using <strong>CNContacts</strong> to fetch phonebook contacts in my iOS device. </p>
  
  <p>When I have a small number of contacts in my phone (say, 50) the contacts are fetched easily.</p>
  
  <p>However, when I have a lot of contacts (say 500-700) it hangs/waits for a long time to fetch these contacts from iOS phonebook into my App's array.</p>
  
  <p>Previously I used <a href="https://github.com/Alterplay/APAddressBook" rel="nofollow">https://github.com/Alterplay/APAddressBook</a> which was a fast library for the previous Apple framework, but now I am using the latest Apple framework.</p>
  
  <p>My code to fetch contacts is ....</p>
  
  <pre><code>#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:&amp;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];
  
          }
  
      }];
  
  
  
  }
  </code></pre>
  
  <p>I was trying to fetch contacts in batches of 20, reloading the table each time. However here it can't reload within the dispatch thread, or simply crashes.</p>
  
  <p>How do I improve this code to fetch contacts quickly?</p>
  
  <p>Thanks.</p>