【问题标题】:Get a list of all contacts on iOS获取 iOS 上所有联系人的列表
【发布时间】:2011-04-14 10:53:32
【问题描述】:

我想获取 iPhone 的所有联系人列表。

我检查了Address Book 参考,我可能遗漏了一些东西,但我没有看到它提供了获取联系人列表的方法。

【问题讨论】:

标签: ios ios4 abaddressbook


【解决方案1】:

也许ABPerson 函数ABAddressBookCopyArrayOfAllPeople 可以吗?

Example:

ABAddressBookRef addressBook = ABAddressBookCreate( );
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );

for ( int i = 0; i < nPeople; i++ )
{
    ABRecordRef ref = CFArrayGetValueAtIndex( allPeople, i );
    ...
}

【讨论】:

  • 注意最近的读者,ABAddressBookCreate() 已被弃用(从 iOS 6 开始)支持ABAddressBookCreateWithOptions(NULL, error)
  • @martin-clayton 当有 5000 多个联系人时它是如何工作的?我们如何管理内存?
  • @sarat 您是否测量了 5000 多个联系人的内存成本?我不确定这是一个问题,至少你在一个循环中分配了太多图像,而不是在每次迭代结束时手动取消分配它们。 (只需使用autoreleasepool{}
【解决方案2】:

确保你有正确的导入

#import <AddressBook/AddressBook.h>

然后你可以得到一个包含所有联系人的 CFArray 对象

CFArrayRef ABAddressBookCopyArrayOfAllPeople (ABAddressBookRef addressBook);

【讨论】:

  • +1 是(目前)包含所需库的唯一答案
【解决方案3】:

在 iOS 6 中,请确保使用 ABAddressBookCreateWithOptions,这是 ABAddressBookCreate 的更新版本

CFErrorRef * error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex numberOfPeople = ABAddressBookGetPersonCount(addressBook);

for(int i = 0; i < numberOfPeople; i++){
  ABRecordRef person = CFArrayGetValueAtIndex( allPeople, i );
  // More code here
}

【讨论】:

【解决方案4】:

使用此代码显示所有姓名 + 姓氏 + 电话号码 (iOS 6)。也适用于模拟器:

CFErrorRef *error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex numberOfPeople = ABAddressBookGetPersonCount(addressBook);

for(int i = 0; i < numberOfPeople; i++) {

    ABRecordRef person = CFArrayGetValueAtIndex( allPeople, i );

    NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonFirstNameProperty));
    NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonLastNameProperty));
    NSLog(@"Name:%@ %@", firstName, lastName);

    ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);

    for (CFIndex i = 0; i < ABMultiValueGetCount(phoneNumbers); i++) {
        NSString *phoneNumber = (__bridge_transfer NSString *) ABMultiValueCopyValueAtIndex(phoneNumbers, i);
        NSLog(@"phone:%@", phoneNumber);
    }

    NSLog(@"=============================================");

}

【讨论】:

【解决方案5】:
ABAddressBookRef addressBook = ABAddressBookCreate( );
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );

for ( int i = 0; i < nPeople; i++ )
{
ABRecordRef ref = CFArrayGetValueAtIndex( allPeople, i );
  ...
}

【讨论】:

    【解决方案6】:

    查看https://github.com/heardrwt/RHAddressBook(2014 年 1 月 254 颗星)。

    使用更简单的 API 为 AddressBook 提供 ObjC 包装器。

    【讨论】:

      【解决方案7】:

      更新iOS 9.0。 Apple 已弃用 AddressBook,现在他们添加了 Contacts 框架:

      添加CNContactStore 属性并像这样定义它:

      self.contactsStrore = [[CNContactStore alloc] init];
      

      然后添加这些方法来读取所有联系人:

      -(void)checkContactsAccess{
      
      [self requestContactsAccessWithHandler:^(BOOL grandted) {
      
          if (grandted) {
      
              CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactNamePrefixKey, CNContactMiddleNameKey, CNContactPhoneNumbersKey]];
              [self.contactsStrore enumerateContactsWithFetchRequest:request error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
      
                  NSLog(@"%@", contact.familyName);
                  NSLog(@"%@", contact.givenName);
                  NSLog(@"%@", contact.namePrefix);
                  NSLog(@"%@", contact.middleName);
                  NSLog(@"%@", contact.phoneNumbers);
                  NSLog(@"=============================================");
              }];
          }
      }];
      }
      
      -(void)requestContactsAccessWithHandler:(void (^)(BOOL grandted))handler{
      
      switch ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]) {
          case CNAuthorizationStatusAuthorized:
              handler(YES);
              break;
          case CNAuthorizationStatusDenied:
          case CNAuthorizationStatusNotDetermined:{
              [self.contactsStrore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
      
                  handler(granted);
              }];
              break;
          }
          case CNAuthorizationStatusRestricted:
              handler(NO);
              break;
      }
      }
      

      iOS 9.0 之前 => 使用 AddressBook 框架。 您必须先检查访问权限并请求访问用户联系人:

      // Prompt the user for access to their Address Book data
      -(void)requestAddressBookAccess
      {
         YourViewController * __weak weakSelf = self;
      
        ABAddressBookRequestAccessWithCompletion(self.addressBook, ^(bool granted, CFErrorRef error)
                                               {
                                                   if (granted)
                                                   {
                                                       dispatch_async(dispatch_get_main_queue(), ^{
                                                           [weakSelf accessGrantedForAddressBook];
      
                                                       });
                                                   }
                                               });
      }
      
      
      
      -(void)checkAddressBookAccess
      {
         switch (ABAddressBookGetAuthorizationStatus())
             {
              // Update our UI if the user has granted access to their Contacts
          case  kABAuthorizationStatusAuthorized:
              [self accessGrantedForAddressBook];
              break;
              // Prompt the user for access to Contacts if there is no definitive answer
          case  kABAuthorizationStatusNotDetermined :
              [self requestAddressBookAccess];
              break;
              // Display a message if the user has denied or restricted access to Contacts
          case  kABAuthorizationStatusDenied:
          case  kABAuthorizationStatusRestricted:
          {
              UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Privacy Warning"
                                                              message:@"Permission was not granted for Contacts."
                                                             delegate:nil
                                                    cancelButtonTitle:@"OK"
                                                    otherButtonTitles:nil];
              [alert show];
          }
              break;
          default:
              break;
       }
         }
      

      【讨论】:

        【解决方案8】:

        感谢 mahesh 和 wzbozon,以下代码对我有用:

        CFErrorRef * error = NULL;
        addressBook = ABAddressBookCreateWithOptions(NULL, error);
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error)
         {
             if (granted)
             {
                 dispatch_async(dispatch_get_main_queue(), ^{
                     CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
                     CFIndex numberOfPeople = ABAddressBookGetPersonCount(addressBook);
        
                     for(int i = 0; i < numberOfPeople; i++){
                         ABRecordRef person = CFArrayGetValueAtIndex( allPeople, i );
        
                         NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonFirstNameProperty));
                         NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonLastNameProperty));
                         NSLog(@"Name:%@ %@", firstName, lastName);
        
                         ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
        
                         NSMutableArray *numbers = [NSMutableArray array];
                         for (CFIndex i = 0; i < ABMultiValueGetCount(phoneNumbers); i++) {
                             NSString *phoneNumber = (__bridge_transfer NSString *) ABMultiValueCopyValueAtIndex(phoneNumbers, i);
                             [numbers addObject:phoneNumber];
                         }
        
                         NSMutableDictionary *contact = [NSMutableDictionary dictionary];
                         [contact setObject:name forKey:@"name"];
                         [contact setObject:numbers forKey:@"numbers"];
        
                         [all_contacts addObject:contact];
                     }
                 });
             }
         });
        

        【讨论】:

          【解决方案9】:

          在我的原始答案中,在此答案的末尾,我展示了如何在 9.0 之前的 iOS 版本中检索联系人,以解决此处其他答案所带来的一些问题。

          但是,如果只支持 iOS 9 及更高版本,则应该使用Contacts 框架,避免使用旧的AddressBook 框架时出现的一些烦人的桥接问题。

          因此,在 iOS 9 中,您将使用 Contacts 框架:

          @import Contacts;
          

          您还需要更新您的Info.plist,添加NSContactsUsageDescription 以解释您的应用需要访问联系人的原因。

          然后执行如下操作:

          CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
          if (status == CNAuthorizationStatusDenied || status == CNAuthorizationStatusRestricted) {
              UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Access to contacts." message:@"This app requires access to contacts because ..." preferredStyle:UIAlertControllerStyleActionSheet];
              [alert addAction:[UIAlertAction actionWithTitle:@"Go to Settings" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                  [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
              }]];
              [alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel 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;
              }
          
              // build array of contacts
          
              NSMutableArray *contacts = [NSMutableArray array];
          
              NSError *fetchError;
              CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[CNContactIdentifierKey, [CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName]]];
          
              BOOL success = [store enumerateContactsWithFetchRequest:request error:&fetchError usingBlock:^(CNContact *contact, BOOL *stop) {
                  [contacts addObject:contact];
              }];
              if (!success) {
                  NSLog(@"error = %@", fetchError);
              }
          
              // you can now do something with the list of contacts, for example, to show the names
          
              CNContactFormatter *formatter = [[CNContactFormatter alloc] init];
          
              for (CNContact *contact in contacts) {
                  NSString *string = [formatter stringFromContact:contact];
                  NSLog(@"contact = %@", string);
              }
          }];
          

          如果支持 iOS 9.0 之前的 iOS 版本,以下是我的回答。

          --

          对您的问题以及此处提供的许多答案的一些反应(未请求许可,未正确处理 ABAddressBookCreateWithOptions 错误或泄漏):

          1. 显然,导入AddressBook 框架:

            #import <AddressBook/AddressBook.h>
            

            @import AddressBook;
            
          2. 您必须请求应用程序访问联系人的权限。例如:

            ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
            
            if (status == kABAuthorizationStatusDenied || status == kABAuthorizationStatusRestricted) {
                // if you got here, user had previously denied/revoked permission for your
                // app to access the contacts and all you can do is handle this gracefully,
                // perhaps telling the user that they have to go to settings to grant access
                // to contacts
            
                [[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
                return;
            }
            
            CFErrorRef error = NULL;
            ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
            
            if (!addressBook) {
                NSLog(@"ABAddressBookCreateWithOptions error: %@", CFBridgingRelease(error));
                return;
            }
            
            ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
                if (error) {
                    NSLog(@"ABAddressBookRequestAccessWithCompletion error: %@", CFBridgingRelease(error));
                }
            
                if (granted) {
                    // if they gave you permission, then just carry on
            
                    [self listPeopleInAddressBook:addressBook];
                } else {
                    // however, if they didn't give you permission, handle it gracefully, for example...
            
                    dispatch_async(dispatch_get_main_queue(), ^{
                        // BTW, this is not on the main thread, so dispatch UI updates back to the main queue
            
                        [[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
                    });
                }
            
                CFRelease(addressBook);
            });
            
          3. 注意以上,我没有使用别人建议的模式:

            CFErrorRef *error = NULL;
            ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
            

            这是不正确的。正如您将在上面看到的,您想要:

            CFErrorRef error = NULL;
            ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
            

            前一种模式不能正确捕捉错误,而后者会。如果error 不是NULL,请不要忘记CFRelease(或像我一样将所有权转让给ARC),否则您将泄露该对象。

          4. 要遍历联系人,您需要:

            - (void)listPeopleInAddressBook:(ABAddressBookRef)addressBook
            {
                NSArray *allPeople = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));
                NSInteger numberOfPeople = [allPeople count];
            
                for (NSInteger i = 0; i < numberOfPeople; i++) {
                    ABRecordRef person = (__bridge ABRecordRef)allPeople[i];
            
                    NSString *firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
                    NSString *lastName  = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
                    NSLog(@"Name:%@ %@", firstName, lastName);
            
                    ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
            
                    CFIndex numberOfPhoneNumbers = ABMultiValueGetCount(phoneNumbers);
                    for (CFIndex j = 0; j < numberOfPhoneNumbers; j++) {
                        NSString *phoneNumber = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phoneNumbers, j));
                        NSLog(@"  phone:%@", phoneNumber);
                    }
            
                    CFRelease(phoneNumbers);
            
                    NSLog(@"=============================================");
                }
            }
            
          5. 我想提请您注意一个相当关键的细节,即"Create Rule"

            Core Foundation 函数的名称表明您何时拥有返回的对象:

            • 名称中嵌入“Create”的对象创建函数;

            • 名称中嵌入了“Copy”的对象复制函数。

            如果您拥有一个对象,则您有责任在完成该对象后放弃所有权(使用 CFRelease)。

            这意味着您有责任释放名称中带有CreateCopy 的任何Core Foundation 函数返回的任何对象。您可以显式调用CFRelease(就像我在上面使用addressBookphoneNumbers 所做的那样),或者,对于支持免费桥接的对象,您可以使用__bridge_transferCFBridgingRelease 将所有权转移给ARC(正如我上面使用allPeoplelastNamefirstNamephoneNumber)。

            静态分析器(在 Xcode 中按 shift+command+B 或从“产品”菜单中选择“分析”)可以识别在许多情况下,您忽略了遵守此“创建规则”并且未能释放适当的对象。因此,每当编写这样的 Core Foundation 代码时,请始终通过静态分析器运行它,以确保您没有任何明显的泄漏。

          【讨论】:

          • 注意:有时电话号码中会有 \U00a0 空格。您可以使用 phoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] componentsJoinedByString:@""]; 删除它们在得到电话字符串后的行中
          • 我猜'if (status == CNAuthorizationStatusDenied || status == CNAuthorizationStatusDenied) {'这行有一个错误,我猜另一个状态是CNAuthorizationStatusRestricted
          【解决方案10】:

          这适用于 ios 7 和 ios 8,希望对您有所帮助......

          NSMutableArray *result = [[NSMutableArray alloc] init];
          CFErrorRef *error = nil;
          ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
          __block BOOL accessGranted = NO;
          
          if (ABAddressBookRequestAccessWithCompletion != NULL){
              dispatch_semaphore_t sema = dispatch_semaphore_create(0);
          
              ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
                  accessGranted = granted;
                  dispatch_semaphore_signal(sema);
              });
              dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
          }
          else{
              accessGranted = YES;
          }
          if (accessGranted){
              // If the app is authorized to access the first time then add the contact
              ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
              CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
              CFIndex numberOfPeople = ABAddressBookGetPersonCount(addressBook);
          
              for (int i=0; i<numberOfPeople; i++){
                  CFStringRef phone;
                  ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
                  CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
                  CFStringRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);
                  NSString *userName = @"NoName";
          
                  userName = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
                  userName = [userName stringByReplacingOccurrencesOfString:@"(null)" withString:@""];
          
                  ABMutableMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
                  CFIndex phoneNumberCount = ABMultiValueGetCount( phoneNumbers );
          
                  phone = nil;
          
                  for ( CFIndex ind= 0; ind<phoneNumberCount; ind++ ){
                      CFStringRef phoneNumberLabel = ABMultiValueCopyLabelAtIndex( phoneNumbers, ind);
                      CFStringRef phoneNumberValue = ABMultiValueCopyValueAtIndex( phoneNumbers, ind);
          
                      // converts "_$!<Work>!$_" to "work" and "_$!<Mobile>!$_" to "mobile"
                      // Find the ones you want here
                      if (phoneNumberLabel != nil){
                          NSStringCompareOptions  compareOptions = NSCaseInsensitiveSearch;
                          if(CFStringCompare(phoneNumberLabel, CFSTR("mobile"),compareOptions)){
                              phone = phoneNumberValue;
                          }
                          phone = phoneNumberValue;
          
                          NSStringCompareOptions  compareOptionss = NSCaseInsensitiveSearch;
                          if(!CFStringCompare(phone, CFSTR("1-800-MY-APPLE"),compareOptionss)){
                              continue;
                          }
                          NSMutableArray *theKeys = [NSMutableArray arrayWithObjects:@"name", @"small_name",@"phone", @"checked", nil];
                          NSMutableArray *theObjects = [NSMutableArray arrayWithObjects:userName, [userName lowercaseString],phone, @"NO", nil];
                          NSMutableDictionary *theDict = [NSMutableDictionary dictionaryWithObjects:theObjects forKeys:theKeys];
                          if (![[functions formatNumber:(__bridge NSString *)(phone)] isEqualToString:[[NSUserDefaults standardUserDefaults]valueForKey:@"phoneNumber"]]){
                              [result addObject:theDict];
                          }
                      }
                  }
              }
          }
          //sort array
          NSSortDescriptor * descriptor = [[NSSortDescriptor alloc] initWithKey:@"small_name"
                                                                      ascending:YES]; // 1
          NSArray * sortedArray = [result sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]];
          

          【讨论】:

          • functions 在最后一个 if 情况下未定义。还有CFStringCompare 尝试将NSStringCompareOptions 转换为NSStringCompareFlags
          【解决方案11】:

          Swift 版本:

          override func viewDidLoad() {
              super.viewDidLoad()
          
              var error: Unmanaged<CFErrorRef>?
          
              var addressBook: ABAddressBook = ABAddressBookCreateWithOptions(nil, &error).takeRetainedValue()
          
          
              if ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.NotDetermined {
                  ABAddressBookRequestAccessWithCompletion(addressBook,  {
          
                      (granted:Bool, error:CFErrorRef!) -> Void in
          
                      self.populateFrom(addressBook: addressBook)
          
                  })
              }
              else if ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Authorized {
          
                  self.populateFrom(addressBook: addressBook)
          
              }
          
          }
          
          func populateFrom(#addressBook:ABAddressBook){
              let allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()
              let nPeople = ABAddressBookGetPersonCount(addressBook)
              for index in 0..<nPeople{
                  let person: ABRecordRef = Unmanaged<ABRecordRef>.fromOpaque(COpaquePointer(CFArrayGetValueAtIndex(allPeople, index))).takeUnretainedValue()
                  let firstName: String = ABRecordCopyValue(person, kABPersonFirstNameProperty).takeUnretainedValue() as? String
                  println("\(firstName.debugDescription)")
          
          
              }
          
          }
          

          【讨论】:

            【解决方案12】:

            这是使用表格视图获取所有联系人的完整演示。

            import UIKit
            import ContactsUI
            import AddressBook
            import Contacts
            
            class ShowContactsVC: UIViewController,CNContactPickerDelegate,UITableViewDelegate,UITableViewDataSource
            {
            
            
            
            @IBOutlet weak var tableView: UITableView!
            let peoplePicker = CNContactPickerViewController()
            let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
            var contacts = [CNContact]()
            var option : Int = 0
            var userAccessGranted : Bool = false
            var dataArray : NSMutableArray?
            
            
            
            
            override func viewDidLoad()
            {
                super.viewDidLoad()
            
                peoplePicker.delegate = self
            
                self.checkIfUserAccessGranted()
            
                self.tableView.delegate = self
                self.tableView.dataSource = self
            
            
                navigationController!.navigationBar.barTintColor = UIColor.grayColor()
            
            
                          if(self.userAccessGranted)
                  {
                     self.tableView.hidden = false
                    fetchContacts()
            
                }
            
            }
            
            func numberOfSectionsInTableView(tableView: UITableView) -> Int
            {
                return 1
            }
            
            func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
            {
                if dataArray == nil {
                    return 0;
                }
                else{
            
            
                return dataArray!.count
            }
            }
            
            func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
            {
                let cell = tableView.dequeueReusableCellWithIdentifier("TableCell", forIndexPath: indexPath) as! ContactsTableViewCell
            
            
            
                let data = dataArray![indexPath.row] as! Data;
                cell.lblName.text = data.name
                cell.imgContact.image = data.image
                return cell
            }
            
            func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
            {
                cell.backgroundColor = UIColor.cyanColor()
            
            }
            
            
            
            
            func checkIfUserAccessGranted()
            {
                appDelegate.requestForAccess { (accessGranted) -> Void in
                    if accessGranted {
                        self.userAccessGranted = true;
                    }else{
                        self.userAccessGranted = false;
                    }
                }
            }
            
            
            
            
            
            func fetchContacts()
            {
            
                dataArray = NSMutableArray()
            
                let toFetch = [CNContactGivenNameKey, CNContactImageDataKey, CNContactFamilyNameKey, CNContactImageDataAvailableKey]
                let request = CNContactFetchRequest(keysToFetch: toFetch)
            
                do{
                    try appDelegate.contactStore.enumerateContactsWithFetchRequest(request) {
                        contact, stop in
                        print(contact.givenName)
                        print(contact.familyName)
                        print(contact.identifier)
            
                        var userImage : UIImage;
                        // See if we can get image data
                        if let imageData = contact.imageData {
                            //If so create the image
                            userImage = UIImage(data: imageData)!
                        }else{
                            userImage = UIImage(named: "no_contact_image")!
                        }
            
                        let data = Data(name: contact.givenName, image: userImage)
                        self.dataArray?.addObject(data)
            
                    }
                } catch let err{
                    print(err)
            
                }
            
                self.tableView.reloadData()
            
            }
            
            func contactPickerDidCancel(picker: CNContactPickerViewController)
            {
                picker.dismissViewControllerAnimated(true, completion: nil)
                self.navigationController?.popToRootViewControllerAnimated(true)
            }
            
            
            
            override func didReceiveMemoryWarning() {
                super.didReceiveMemoryWarning()
                // Dispose of any resources that can be recreated.
            }
            
            
            
            }
            
            
            
            
            import UIKit
            
            class Data {
            
            
                let name : String
                let image : UIImage
            
                init(name : String, image : UIImage) {
                    self.image = image
                    self.name = name
                }
            
            }
            

            【讨论】:

            • 这个代码是不是也用于生成联系人的二维码?
            【解决方案13】:

            如果你想按字母顺序排序,你可以使用下面的代码。

             CFErrorRef *error = NULL;
            ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
            CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
            CFIndex numberOfPeople = ABAddressBookGetPersonCount(addressBook);
            
            CFMutableArrayRef peopleMutable = CFArrayCreateMutableCopy(kCFAllocatorDefault,
                                                                       CFArrayGetCount(allPeople),
                                                                       allPeople);
            
            CFArraySortValues(peopleMutable,
                              CFRangeMake(0, CFArrayGetCount(peopleMutable)),
                              (CFComparatorFunction) ABPersonComparePeopleByName,
                              kABPersonSortByFirstName);
            

            【讨论】:

              猜你喜欢
              • 2016-03-02
              • 1970-01-01
              • 1970-01-01
              • 2015-06-16
              • 1970-01-01
              • 2012-09-15
              • 1970-01-01
              • 1970-01-01
              • 2011-05-19
              相关资源
              最近更新 更多