2010-09-19 90 views
68

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

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

+1

help:http://stackoverflow.com/a/16608766/763142 – 2013-07-16 13:37:41

回答

96

也许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); 
    ... 
} 
+0

完全感谢您的宝贵帮助。不应该将此功能作为ABAddressBook的一部分吗? – Chiron 2010-09-20 00:03:40

+0

这是真棒...我以前从其他论坛问同样的问题,但没有人回答正确,在这种正确的方式..谢谢马丁.. – Aldee 2012-01-27 10:19:19

+0

我遵循相同的程序,但我无法获取联系人来自设备。虽然当我在模拟器中运行它工作正常。仍然不知道为什么不在设备上工作。你能告诉我最新的问题..? – 2013-10-07 10:55:41

12

请确保您有您可以开始使用

CFArrayRef ABAddressBookCopyArrayOfAllPeople (ABAddressBookRef addressBook); 
+1

+1为是唯一的答案(目前)已包括所需的库 – 2014-11-06 05:19:04

10

与所有接触CFArray对象在iOS 6中正确导入

#import <AddressBook/AddressBook.h> 

然后,使确定您使用ABAddressBookCreateWithOptions,这是的更新版本10

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 
} 
+1

运作良好,并在文档解释了如何将它按字母顺序排序:[AddressBookProgrammingGuideforiPhone](HTTP ://developer.apple.com/library/ios/#documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/Chapters/DirectInteraction.html) – Patrick 2013-06-18 16:01:24

+0

@Patrick这个字母顺序排列姓氏,任何想法如何做到这一点的第一个名字呢? – Sheharyar 2014-08-30 10:48:59

+0

@Patrick请检查这个问题并帮助我解决它。 https://开头计算器。com/q/47506554/2910061 – ilesh 2017-11-27 09:14:00

23

使用此代码显示所有名称+姓氏+电话号码(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

请确保您不要忘记首先询问许可。这是另一个示例,与这一个很好地工作,http://stackoverflow.com/questions/12648244/programmatically-request-access-to-contacts – atreat 2013-11-04 00:53:29

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

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

更新iOS 9.0。苹果已否决AddressBook,现在他们已经添加Contacts框架:

添加CNContactStore财产,并将其定义是这样的:

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

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

​​

的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; 
} 
    } 
6

感谢马赫什和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]; 
      } 
     }); 
    } 
}); 
99

在我原来的答复,在年底在这个答案中,我展示了如何在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"

    核心基础功能有名字指示您何时拥有返回对象:

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

    • 在名称中嵌入“Copy”的对象复制功能。

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

    这意味着您将负责释放任何Core Foundation功能返回的名称中带有CreateCopy的任何对象。您可以拨打CFRelease明示或对于支持免费桥接的对象,你可以转移所有权__bridge_transferCFBridgingRelease到ARC(如我addressBookphoneNumbers上面那样)(我用allPeoplelastNamefirstName上面做了, phoneNumber)。

    静态分析(按转变 + 命令 + 在Xcode或选择“分析”,从“产品”菜单)可以找出很多情况下,你能认识到这种“创建规则”和未能发布适当的对象。因此,无论何时编写这样的Core Foundation代码,都要通过静态分析器运行它,以确保您没有任何明显的泄漏。

+1

注意:有时电话号码将有\ u00a0空格在其中。您可以使用phoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] componentsJoinedByString:@“”]将其删除。在获取电话字符串后的行中 – 2014-11-06 05:55:44

+1

非常有用的答案,涵盖了重要的实施细节。谢谢,罗布。如果我是这个话题的作者,我会接受你的回答是正确的。 – 2015-01-20 13:22:34

+0

感谢@Rob一个简单易行的答案 – 2015-02-19 07:51:56

1

这适用于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]]; 
+0

上一个'if'情况下的函数未定义。另外'CFStringCompare'试图将'NSStringCompareOptions'转换为'NSStringCompareFlags'。 – Raptor 2015-10-29 11:24:01

5

斯威夫特版本:

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)") 


    } 

} 
0

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

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 
    } 

} 
+0

感谢兄弟:D,如何解决这个问题? ''AppDelegate'类型的值没有成员'contactStore'' – 2016-09-15 11:02:36

0

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

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);