编程请求访问联系人(Programmatically Request Access to Conta

2019-06-18 09:00发布

由于更新到iOS 6我发现我的代码来将联系人添加到iPhone的通讯录不再起作用。 我相信这是一个权限相关的问题,因为苹果现在需要(固定访问联系人之前用户权限这一问题)。

我预计应用自动询问权限访问联系人,就像下面的截图,但事实并非如此。 尝试添加联系人,只不过没有用ABAddressBookErrorDomain error 1

我需要以编程方式启动访问联系人请求对话框? 如何做到这一点?

Answer 1:

按照这个文件对苹果的网站(倒在页面中间滚动到隐私),访问地址簿必须被授予后,始可进入程序。 以下是我落得这样做。

  #import <AddressBookUI/AddressBookUI.h>

  // Request authorization to Address Book
  ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);

  if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
    ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
      if (granted) {
          // First time access has been granted, add the contact
          [self _addContactToAddressBook];
      } else {
          // User denied access
          // Display an alert telling user the contact could not be added
      }
    });
  }
  else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
    // The user has previously given access, add the contact
    [self _addContactToAddressBook];
  }
  else {
    // The user has previously denied access
    // Send an alert telling user to change privacy setting in settings app
  }

更新对于iOS 9及更高版本:

从苹果的网站:

重要

地址簿UI框架iOS中9.使用过时的ContactsUI框架,而不是定义的API。 要了解更多信息,请参阅ContactsUI



Answer 2:

那做了完美的把戏我!

在iOS6的,苹果推出新的隐私控制,用户可以控制联系人和日历的每个应用程序的accessment。 所以,在代码方面,你需要添加一些方式来请求许可。 在iOS5中或之前,我们可以随时拨打

ABAddressBookRef addressBook = ABAddressBookCreate();

获得地址簿没有任何问题,但是在iOS6的,如果你没有权限,此调用将只返回空指针。 这就是为什么我们需要改变的方法来获取ABAddressBookRef。

__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
    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);
    dispatch_release(sema);   
}
else { // we're on iOS 5 or older
    accessGranted = YES;
}

if (accessGranted) {
    // Do whatever you want here.
}

在代码中,旗语用于阻止,直到响应,而ABAddressBookRequestAccessWithCompletion会请求许可,如果应用程序之前没有问。 否则,它只会按照设置 - 隐私 - 联系设置。

来源: http://programmerjoe.blogspot.com/2012/10/ios6-permissions-contacts.html



Answer 3:

对于接触框架:

- (void)checkPermissionForCNContacts
{
    switch ([CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts])
    {
        case CNAuthorizationStatusNotDetermined:
        {
            [[[CNContactStore alloc] init] requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
                if (granted == YES)
                    [self showCNContactPicker];
            }];
        }
            break;
        case CNAuthorizationStatusRestricted:
        case CNAuthorizationStatusDenied:
                // Show custom alert
            break;
        case CNAuthorizationStatusAuthorized:
            [self showCNContactPicker];
            break;
    }
}


Answer 4:

ABAddressBookRef addressBook = ABAddressBookCreate();

__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
    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);
    dispatch_release(sema);
}
else { // we're on iOS 5 or older
    accessGranted = YES;
}

if (accessGranted) {
    if(self.isContactsChanged)
    {
        {
            self.isContactsChanged=NO;
            CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
             ABAddressBookRegisterExternalChangeCallback(addressBook, addressBookChanged, self);

            int allPeopleCount = CFArrayGetCount(allPeople);

            NSMutableArray *contactArrTemp = [[NSMutableArray alloc]init];

            __block int noNumberCount=1;
            managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
            newMoc = [[NSManagedObjectContext alloc] init];
            [newMoc setPersistentStoreCoordinator:[[AppDelegate getAppDelegate] persistentStoreCoordinator]];
            [self DeleteAllPhoneContact];
            NSNotificationCenter *notify = [NSNotificationCenter defaultCenter];
            [notify addObserver:self
                       selector:@selector(mergeChanges:)
                           name:NSManagedObjectContextDidSaveNotification
                         object:newMoc];
            self.backgroundQueue = dispatch_queue_create("com.storephonecontacts.bgqueue", NULL);
            __block NSMutableDictionary *dic;
            __block NSString *strTime,*strName,*strMobile,*strEmail,*strNotes;
            __block NSDate *nsDate;
            dispatch_async(self.backgroundQueue, ^{

                NSMutableDictionary *dict =nil;
                for (int i = 0; i < allPeopleCount; i++)
                {

                    dic = [[NSMutableDictionary alloc]init];
                    ABRecordRef record = CFArrayGetValueAtIndex(allPeople,i);
                    NSDate *date = (NSDate*)ABRecordCopyValue(record, kABPersonCreationDateProperty);
                    nsDate = [date retain];

                    NSDateFormatter *formatterTime = [[NSDateFormatter alloc] init];
                    [formatterTime setDateFormat:@"hh.mm"];
                    NSString    *dateStrPhone = [formatterTime stringFromDate:date];
                    strTime = [dateStrPhone retain];
                    [formatterTime release];

                    NSString *name = (NSString*)ABRecordCopyValue(record, kABPersonFirstNameProperty);
                    if([name length]>0)
                        name = [name stringByAppendingString:@" "];
                    NSString *name1 = (NSString*)ABRecordCopyValue(record, kABPersonLastNameProperty);
                    if([name1 length]>0)
                    {
                        if([name length]>0)
                            name = [name stringByAppendingString:name1];
                        else
                            name = (NSString*)ABRecordCopyValue(record, kABPersonLastNameProperty);
                    }
                    if([name length]>0)
                        strName = [name retain];
                    else
                        strName = [@"noName" retain];

                    //to save notes
                    NSString *notes = (NSString*)ABRecordCopyValue(record, kABPersonNoteProperty);
                    if(notes == NULL){
                        strNotes = @"noNotes";
                    }
                    else{
                        strNotes = [notes retain];
                    }
                    //for image
                    if (!ABPersonHasImageData(record)){

                    }
                    else{
                        CFDataRef imageData = ABPersonCopyImageData(record);
                        UIImage *image = [UIImage imageWithData:(NSData *) imageData];
                        [dic setObject:image forKey:@"image"];
                        CFRelease(imageData);
                    }
                    //To set Mobile
                    NSMutableArray* mobileArray = [[NSMutableArray alloc] init];
                    ABMutableMultiValueRef multi = ABRecordCopyValue(record, kABPersonPhoneProperty);
                    if (ABMultiValueGetCount(multi) > 0) {
                        // collect all emails in array
                        for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i++) {

                            CFStringRef mobileRef = ABMultiValueCopyValueAtIndex(multi, i);
                            CFStringRef locLabel = ABMultiValueCopyLabelAtIndex(multi, i);
                            NSString *phoneLabel =(NSString*) ABAddressBookCopyLocalizedLabel(locLabel);

                            if([phoneLabel isEqualToString:@"mobile"])
                                [mobileArray addObject:(NSString *)mobileRef];
                            else if([phoneLabel isEqualToString:@"iPhone"])
                                [mobileArray addObject:(NSString *)mobileRef];
                            else if([phoneLabel isEqualToString:@"home"])
                                [mobileArray addObject:(NSString *)mobileRef];
                            else if([phoneLabel isEqualToString:@"work"])
                                [mobileArray addObject:(NSString *)mobileRef];
                            else if([phoneLabel isEqualToString:@"main"])
                                [mobileArray addObject:(NSString *)mobileRef];
                            else if([phoneLabel isEqualToString:@"other"])
                                [mobileArray addObject:(NSString *)mobileRef];
                            CFRelease(mobileRef);
                            CFRelease(locLabel);
                        }
                    }
                    CFRelease(multi);
                    if([mobileArray count]>0)
                        strMobile = [[mobileArray objectAtIndex:0]retain];
                    else{
                        NSString *str=[NSString stringWithFormat:@"noNumber%i",noNumberCount];
                        strMobile = [str retain];
                        noNumberCount++;
                    }
                    [mobileArray release];

                    //To set E-mail
                    NSMutableArray* emailArray = [[NSMutableArray alloc] init];
                    multi = ABRecordCopyValue(record, kABPersonEmailProperty);
                    if (ABMultiValueGetCount(multi) > 0) {
                        // collect all emails in array
                        for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i++) {
                            CFStringRef emailRef = ABMultiValueCopyValueAtIndex(multi, i);
                            [emailArray addObject:(NSString *)emailRef];
                            CFRelease(emailRef);
                        }
                    }

                    CFRelease(multi);
                    if([emailArray count]>0)
                        strEmail = [[emailArray objectAtIndex:0]retain];
                    else
                        strEmail = [@"noemail" retain];
                    [emailArray release];

                    bool addBool = NO;

                    if([strName isEqualToString:@"noName"]){
                        if([strEmail isEqualToString:@"noemail"]){

                        }
                        else{
                            [dic setObject:strEmail forKey:@"name"];
                            addBool = YES;
                        }

                        if(addBool == NO){
                            if([strMobile isEqualToString:@"noNumber"]){

                            }
                            else{
                                [dic setObject:strMobile forKey:@"name"];
                                addBool = YES;
                            }
                        }
                    }
                    else{
                        [dic setObject:strName forKey:@"name"];
                        addBool = YES;
                    }
                    [dic setObject:strEmail forKey:@"email"];
                    [dic setObject:strMobile forKey:@"mobile"];
                    [dic setObject:nsDate forKey:@"date"];
                    [dic setObject:strTime forKey:@"time"];
                    [dic setObject:strNotes forKey:@"notes"];

                    if(addBool == YES)
                        [contactArrTemp addObject:dic];

                    if([strMobile hasPrefix:@"0"]){
                        NSString *contactNumber=[strMobile stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:@""];
                        if(contactNumber.length>7)
                            [dic setObject:@"iPhone" forKey:@"ContactType"];

                    }
                    else {
                        if(strMobile.length>9)
                            [dic setObject:@"iPhone" forKey:@"ContactType"];

                    }
                    if(![[dic objectForKey:@"ContactType"] isKindOfClass:[NSNull class]] && [dic objectForKey:@"ContactType"])
                    {
                        [self InsertContactWithContactInfoDictionary:dic];
                    }
                    [strName release];
                    [nsDate release];
                    [strEmail release];
                    [strMobile release];
                    [strTime release];
                    [strNotes release];
                    [dic release];
                }
                dispatch_async(self.backgroundQueue, ^(void){ [self gcdDidFinishaddfebriteParsing:dict]; });
                dispatch_release(self.backgroundQueue);
                self.backgroundQueue=nil;
            });

        }
    }
    else
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"PhoneContactsSaved" object:nil userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:@"Successful"]];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"updateContacts" object:nil userInfo:[NSDictionary dictionaryWithObject:@"success" forKey:@"update"]];
    }
}


Answer 5:

有一些问题与yunas在Xcode5上iOS6.1代码。 对于一些小adaptions它为我工作。

问题是在IOS 6中ARC,没有允许dispatch_release(sema); 这里是工作的代码。 注:我用m_addressbook代替addressbook作为ABAddressBookRef!

ViewController.m

#import "ViewController.h"
#import <AddressBook/AddressBook.h>
#import <AddressBook/ABAddressBook.h>
#import <AddressBook/ABPerson.h>

@interface ViewController ()

@property (nonatomic, strong) NSMutableArray* contactList;

@end

@implementation ViewController

- (void)viewDidLoad
{
  [super viewDidLoad];

  ABAddressBookRef m_addressbook =  ABAddressBookCreateWithOptions(NULL, NULL);

  __block BOOL accessGranted = NO;
  if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
      dispatch_semaphore_t sema = dispatch_semaphore_create(0);
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
          @autoreleasepool {
              // Write your code here...
              // Fetch data from SQLite DB
          }
      });

      ABAddressBookRequestAccessWithCompletion(m_addressbook, ^(bool granted, CFErrorRef error) {
          accessGranted = granted;
          dispatch_semaphore_signal(sema);
      });
      dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
  }
  else { // we're on iOS 5 or older
      accessGranted = YES;
  }

  if (accessGranted) {
  // do your stuff
  }
}

// ...


Answer 6:

- (void)viewDidLoad
{
    [super viewDidLoad];


    [self loadPhoneContacts];
}



-(void)loadPhoneContacts{

    ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();

    if (status == kABAuthorizationStatusDenied) {
        // 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 (error) {
        NSLog(@"ABAddressBookCreateWithOptions error: %@", CFBridgingRelease(error));
        if (addressBook) CFRelease(addressBook);
        return;
    }

    if (status == kABAuthorizationStatusNotDetermined) {

        // present the user the UI that requests permission to contacts ...

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

            if (addressBook) CFRelease(addressBook);
        });

    } else if (status == kABAuthorizationStatusAuthorized) {
        [self listPeopleInAddressBook:addressBook];
        if (addressBook) CFRelease(addressBook);
    }
}

- (void)listPeopleInAddressBook:(ABAddressBookRef)addressBook
{
    NSInteger numberOfPeople = ABAddressBookGetPersonCount(addressBook);
    NSArray *allPeople = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));

    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 i = 0; i < numberOfPhoneNumbers; i++) {
            NSString *phoneNumber = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phoneNumbers, i));
            NSLog(@"  phone:%@", phoneNumber);
        }

        CFRelease(phoneNumbers);

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


Answer 7:

如果有人在iOS5中有问题,然后通讯录使用

ABAddressBookRef addressBook = ABAddressBookCreate(); 

的insted的

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL,NULL);


Answer 8:

ABAddressBookRequestAccessWithCompletion(ABAddressBookCreateWithOptions(NULL, nil), ^(bool granted, CFErrorRef error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (!granted){
                    [[[UIAlertView alloc] initWithTitle:@"Contacts Access Denied"
                                                message:@"This app requires access to your device's Contacts.\n\nPlease enable Contacts access for this app in Settings / Privacy / Contacts"
                                               delegate:nil
                                      cancelButtonTitle:@"Dismiss"
                                      otherButtonTitles:nil] show];
            } else {
                //access authorized
            }
        });
    });

对于加说明,以提醒在InfoPlist.strings使用。

NSContactsUsageDescription = "TESTING!";



Answer 9:

斯威夫特3.不要忘记导入联系人

func requestForContactAccess(completionHandler: @escaping (_ accessGranted: Bool) -> Void) {
    let authorizationStatus = CNContactStore.authorizationStatus(for: CNEntityType.contacts)
    switch authorizationStatus {
    case .authorized:
        completionHandler(true)
    case .denied, .notDetermined:
        self.contactStore.requestAccess(for: CNEntityType.contacts, completionHandler: { (access, accessError) -> Void in
            if access {
                completionHandler(access)
            } else {
                if authorizationStatus == CNAuthorizationStatus.denied {
                    DispatchQueue.main.async(execute: { () -> Void in
                        let message = "\(accessError!.localizedDescription)\n\nPlease allow the app to access your contacts through the Settings."
                        self.showMessage(message: message)
                    })
                }
            }
        })
    default:
        completionHandler(false)
    }
}


Answer 10:

与iOS 6你要问权限这样

requestAccessToEntityType:EKEntityTypeEvent completion:


Answer 11:

为了在IOS获取通讯录

- (void)retreiveAllContacts
{
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);

CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);

if (!people) {
    return ;
}

CFMutableArrayRef peopleMutable = CFArrayCreateMutableCopy(kCFAllocatorDefault,
                                                           CFArrayGetCount(people),
                                                           people);

CFArraySortValues(peopleMutable,
                  CFRangeMake(0, CFArrayGetCount(peopleMutable)),
                  (CFComparatorFunction) ABPersonComparePeopleByName,
                  (void*) ABPersonGetSortOrdering());

NSMutableArray *contacts = [[NSMutableArray alloc] initWithCapacity:CFArrayGetCount(peopleMutable)];

for (CFIndex i = 0; i < CFArrayGetCount(peopleMutable); i++)
{

    ABRecordRef person = CFArrayGetValueAtIndex(peopleMutable, i);

    int32_t recId  =  ABRecordGetRecordID(person);

    NSString * abId = [NSString stringWithFormat:@"%d", recId];

    ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);

    ABMultiValueRef emailIds = ABRecordCopyValue(person, kABPersonEmailProperty);


    NSString* firstName = (__bridge NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);

    NSString* lastName = (__bridge NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);

    NSString* companyName = (__bridge NSString*)ABRecordCopyValue(person, kABPersonOrganizationProperty);

    NSString* displayName = [firstName ? firstName : @"" stringByAppendingFormat:@" %@", lastName ? lastName : @""];

    displayName = [displayName stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" "]];


    NSMutableDictionary* contactInfo = [[NSMutableDictionary alloc] init];

    if(ABPersonHasImageData(person))
    {
        CFDataRef imageDataRef = ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatThumbnail);

        NSData * imageData = (__bridge NSData *)imageDataRef;

        UIImage * thumbImage = [UIImage imageWithData:imageData];

        [contactInfo setObject:thumbImage forKey:@"picture"];
    }

    if(!firstName)
        firstName = @"";

    if (!lastName)
        lastName = @"";

    if(!displayName)
        displayName = @"";

    if(!companyName)
        companyName = @"";

   // [contactInfo setObject:[firstName capitalizedString] forKey:kFirstNameKey];

    //[contactInfo setObject:[lastName capitalizedString] forKey:kLastNameKey];

    [contactInfo setObject:[displayName capitalizedString] forKey:@"name"];

    [contactInfo setObject:abId forKey:@"ABID"];


  //  [contactInfo setObject:companyName forKey:kCompanyNameKey];

    NSMutableArray* phoneNumbersList = [[NSMutableArray alloc] init];

    for (CFIndex j=0; j < ABMultiValueGetCount(phoneNumbers); j++)
    {
        NSString* phone = (__bridge NSString*)ABMultiValueCopyValueAtIndex(phoneNumbers, j);

        CFStringRef localizedLabel = ABMultiValueCopyLabelAtIndex(phoneNumbers,j);

      //  NSString *phoneLabel =(__bridge NSString*) ABAddressBookCopyLocalizedLabel(localizedLabel);


        if( phone)
        {
            //                NSLog(@"validatedPhone: %@", validatedPhone);


            [phoneNumbersList addObject:phone];
        }

        if (localizedLabel) {
            //                            NSLog(@"localizedLabel: %@", localizedLabel);
            CFRelease(localizedLabel);
        }
    }

    if(phoneNumbers)
    {
        //                        NSLog(@"phoneNumbers: %@", phoneNumbers);

        CFRelease(phoneNumbers);

        //            NSLog(@"phoneNumbers Release: %@", phoneNumbers);

    }

    [contactInfo setObject:phoneNumbersList forKey:@"phoneNumbers"];

    NSMutableArray * emailList = [[NSMutableArray alloc] init];

    for (CFIndex j=0; j < ABMultiValueGetCount(emailIds); j++)
    {
        NSString* email = (__bridge NSString*)ABMultiValueCopyValueAtIndex(emailIds, j);

        CFStringRef localizedLabel = ABMultiValueCopyLabelAtIndex(emailIds, j);


        if(email)
        {


            [emailList addObject:email];
        }

    }

    if(emailIds)
    {
        CFRelease(emailIds);

    }

    if(emailList && [emailList count])
        [contactInfo setObject:emailList forKey:@"emails"];

    if ([phoneNumbersList count] > 0 || [emailList count] > 0) {
        [contacts addObject:contactInfo];
    }
}

//CFRelease();
CFRelease(people);

if([contacts count])
{
    [self createiOSContactsDataSourceWithFeed:contacts];
}

}


Answer 12:

这段代码演示了如何与标签标签设置权限以及如何让所有从手机联系人,并显示在列表中的联系人

var contactStore = CNContactStore()
var contactArray = [CNContact]()

func getContacts()
{

    if CNContactStore.authorizationStatus(for: .contacts) == .notDetermined
    {

        contactStore.requestAccess(for: .contacts, completionHandler: { (authorized:Bool, error:Error?) in

            if authorized {



                let requestForContacts = CNContactFetchRequest(keysToFetch: [CNContactFormatter.descriptorForRequiredKeys(for: CNContactFormatterStyle.fullName), CNContactPhoneNumbersKey as CNKeyDescriptor, CNContactImageDataKey as CNKeyDescriptor, CNContactNicknameKey as CNKeyDescriptor])
                do{
                    try self.contactStore.enumerateContacts(with: requestForContacts) { (contacts : CNContact, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
                        self.contactArray.append(contacts)
                        //print("hello")
                    }
                }
                catch {
                    print("EXCEPTION COUGHT")
                }
            }
        })
    }
    else if CNContactStore.authorizationStatus(for: .contacts) == .authorized
    {
        let requestForContacts = CNContactFetchRequest(keysToFetch: [CNContactFormatter.descriptorForRequiredKeys(for: CNContactFormatterStyle.fullName), CNContactPhoneNumbersKey as CNKeyDescriptor, CNContactImageDataKey as CNKeyDescriptor, CNContactNicknameKey as CNKeyDescriptor])
        do{
            try self.contactStore.enumerateContacts(with: requestForContacts) { (contacts : CNContact, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
                self.contactArray.append(contacts)
            }
        }
        catch {

        }

    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    getContacts()

}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    //print(contactArray)
    return contactArray.count

}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "defaultCell")

    if cell != nil{

        //var dig = String()
        var hmdig = [String]()

        let names = contactArray[indexPath.row]
        print(names)

        let name1 = names.givenName+" "+names.middleName+" "+names.familyName

        for number in names.phoneNumbers
        {
            let phoneNumber = number.value

            let dig = (phoneNumber.value(forKey: "digits") as? String)!
            hmdig.append(dig)

        }

        // Set the contact image.
        if let imageData = names.imageData
        {
            let myImage = cell?.viewWithTag(30) as! UIImageView
            myImage.image = UIImage(data: imageData)
        }


//            let niknm = names.nickname

        let nameLable1 = cell?.viewWithTag(10) as! UILabel
                nameLable1.text = name1

        let nameLable2 = cell?.viewWithTag(20) as? UILabel

            nameLable2?.text = hmdig.joined(separator: ",\n")

//           let nameLable3 = cell?.viewWithTag(40) as? UILabel
//                nameLable3?.text = niknm


        return cell!

    }
    else{

        return UITableViewCell()
    }
}


文章来源: Programmatically Request Access to Contacts