代码之家  ›  专栏  ›  技术社区  ›  Chiron

获取iOS上所有联系人的列表

  •  70
  • Chiron  · 技术社区  · 15 年前

    我想得到一个iPhone所有联系人的列表。

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

    13 回复  |  直到 8 年前
        1
  •  97
  •   martin clayton egrunin    15 年前

    也许 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 );
        ...
    }
    
        2
  •  102
  •   Sivajee Battina    8 年前

    在我的原始答案中,在这个答案的最后,我展示了如何在9.0之前的iOS版本中检索联系人,以解决这里其他答案带来的一些问题。

    但是,如果只支持iOS 9和更高版本,那么应该使用 Contacts 框架,避免在使用旧的框架时遇到一些烦人的桥接问题 AddressBook 框架。

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

    @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. 显然,导入 通讯录 框架:

      #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" :

      核心基础函数具有当您拥有返回对象时指示的名称:

      • 具有__的对象创建函数 Create 嵌入到名称中;

      • 对象复制函数 Copy 嵌入到名称中。

      如果您拥有一个对象,当您完成它时,您有责任放弃它的所有权(使用cfrelease)。

      这意味着您承担释放任何核心基础函数返回的任何对象的责任。 创造 拷贝 以这个名字。你可以打任何一个电话 C释放 明确地(正如我上面所做的 addressBook phoneNumbers )或者,对于支持免费桥接的对象,可以使用 __bridge_transfer CFBridgingRelease (如上所述 allPeople , lastName , firstName phoneNumber )

      静态分析仪(按 转移 + 命令 + 在xcode中或从“产品”菜单中选择“分析”)可以识别出许多情况,在这些情况下,您忽略了观察这个“创建规则”,并且未能释放适当的对象。因此,每当编写这样的核心基础代码时,总是通过静态分析器来确保没有明显的泄漏。

        3
  •  23
  •   Denis Kutlubaev    13 年前

    使用此代码显示所有姓名+姓氏+电话号码(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(@"=============================================");
    
    }
    
        4
  •  12
  •   Hector204    15 年前

    确保正确导入

    #import <AddressBook/AddressBook.h>
    

    然后,您可以使用

    CFArrayRef ABAddressBookCopyArrayOfAllPeople (ABAddressBookRef addressBook);
    
        5
  •  10
  •   danielM    13 年前

    在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
    }
    
        6
  •  9
  •   Hossam Ghareeb    10 年前

    更新 对于 iOS 9.0 . 苹果已弃用 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之前=使用 通讯录 框架。 您必须先检查访问权限并请求访问用户联系人:

    // 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;
     }
       }
    
        7
  •  7
  •   Roozbeh Zabihollahi    12 年前

    多亏了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];
                 }
             });
         }
     });
    
        8
  •  5
  •   Bojan Bozovic    10 年前

    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)")
    
    
        }
    
    }
    
        9
  •  4
  •   vaughan    12 年前

    退房 https://github.com/heardrwt/RHAddressBook (254星,2014年1月)。

    为带有更简单的API的地址簿提供一个objc包装器。

        10
  •  1
  •   KumarS    11 年前

    这适用于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]];
    
        11
  •  0
  •   mahesh chowdary    12 年前
    ABAddressBookRef addressBook = ABAddressBookCreate( );
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
    CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );
    
    for ( int i = 0; i < nPeople; i++ )
    {
    ABRecordRef ref = CFArrayGetValueAtIndex( allPeople, i );
      ...
    }
    
        12
  •  0
  •   AlBlue RACGAMERUP    10 年前

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

    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
  •  0
  •   Emre Gürses    9 年前

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

     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);
    
    推荐文章