Получить список всех контактов на iOS


Я хочу получить список всех контактов iPhone.

проверил Address Book ссылка, я могу пропустить что-то, но я не видел, что он предоставляет метод, чтобы получить список контактов.

13 69

13 ответов:

возможно ABPerson функции ABAddressBookCopyArrayOfAllPeople может сделать?

пример:

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

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

в моем первоначальном ответе в конце этого ответа я показываю, как получить контакты в версиях iOS до 9.0 таким образом, чтобы решить некоторые проблемы, связанные с другими ответами здесь.

но, если только поддержка 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 до iOS 9.0.

--

несколько реакций не только на ваш вопрос, но и на многие ответы, представленные здесь (которые либо не запрашивают разрешения, не обрабатывают 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" встроенный в имени;

    • объект-дублирование функций "Copy " встроенный в имя.

    если у вас есть объект, это ваша ответственность, чтобы отказаться от собственности (с помощью CFRelease), когда вы закончили с ним.

    это означает, что вы несете ответственность за освобождение любого объекта, возвращаемого любой основной функцией Foundation с помощью Create или Copy в имя. Вы можете либо позвонить CFRelease явно (как я сделал выше с addressBook и phoneNumbers) или, для объектов, которые поддерживают бесплатный мост, вы можете передать право собственности на ARC с __bridge_transfer или CFBridgingRelease (как я сделал выше с allPeople,lastName,firstName и phoneNumber).

    статический анализатор (нажмите клавишу shift+команда+B в Xcode или выберите "анализ" из меню "продукт") может определить многие ситуации, в которых вы пренебрегли соблюдать это "правило создания" и не смогли освободить соответствующие объекты. Таким образом, всякий раз, когда вы пишете код Core Foundation, всегда запускайте его через статический анализатор, чтобы убедиться, что у вас нет никаких очевидных утечек.

используйте этот код для отображения всех имен + фамилий + телефонных номеров (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(@"=============================================");

}

убедитесь, что у вас есть соответствующие импортные

#import <AddressBook/AddressBook.h>

тогда вы можете получить объект CFArray со всеми контактами с помощью

CFArrayRef ABAddressBookCopyArrayOfAllPeople (ABAddressBookRef addressBook);

В 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
}

обновление на 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;
 }
   }

благодаря 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];
             }
         });
     }
 });

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


    }

}

проверить https://github.com/heardrwt/RHAddressBook (254 звезды 01/2014).

предоставляет оболочку ObjC для адресной книги с гораздо более простым API.

это работает для 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]];
ABAddressBookRef addressBook = ABAddressBookCreate( );
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );

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

это полная демонстрация для извлечения всех контактов с табличным представлением.

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
    }

}

Если вы хотите отсортировать в алфавитном порядке, вы можете использовать ниже код.

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