ขอการเข้าถึงผู้ติดต่อโดยทางโปรแกรม


109

ตั้งแต่อัปเดตเป็น iOS 6 ฉันสังเกตเห็นว่ารหัสของฉันเพื่อเพิ่มผู้ติดต่อลงในสมุดที่อยู่ของ iPhone ใช้งานไม่ได้อีกต่อไป ฉันเชื่อว่านี่เป็นปัญหาที่เกี่ยวข้องกับการอนุญาตเนื่องจากตอนนี้ Apple ต้องได้รับอนุญาตจากผู้ใช้ก่อนที่จะเข้าถึงรายชื่อติดต่อ (แก้ไขปัญหานี้ )

ฉันคาดว่าแอปจะขออนุญาตเข้าถึงผู้ติดต่อโดยอัตโนมัติเช่นในภาพหน้าจอด้านล่าง แต่ไม่ได้ ABAddressBookErrorDomain error 1พยายามที่จะเพิ่มรายชื่อเพียงแค่ล้มเหลวด้วย

ฉันจำเป็นต้องเปิดช่องโต้ตอบคำขอการเข้าถึงผู้ติดต่อโดยใช้โปรแกรมหรือไม่? เป็นอย่างไรบ้าง?

เข้าถึงผู้ติดต่อ

คำตอบ:


180

ตามเอกสารฉบับนี้บนเว็บไซต์ของแอปเปิ้ล (เลื่อนลงไปที่ความเป็นส่วนตัวในช่วงกลางของหน้า) การเข้าถึงสมุดที่อยู่ต้องได้รับอนุญาตก่อนที่จะสามารถเข้าถึงโปรแกรม นี่คือสิ่งที่ฉันทำ

  #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 และใหม่กว่า:

จากเว็บไซต์ Apple:

สำคัญ

เฟรมเวิร์ก UI ของสมุดรายชื่อเลิกใช้งานแล้วใน iOS 9 ใช้ API ที่กำหนดไว้ในเฟรมเวิร์ก ContactsUI แทน หากต้องการเรียนรู้เพิ่มเติมโปรดดูContactsUI


แก้ไขคำตอบของฉันเพื่อรวมการนำเข้า โปรดทราบว่าคุณต้องเชื่อมโยงกรอบงาน AddressBook และ AddressBookUI กับโครงการของคุณในแท็บขั้นตอนการสร้าง
Kyle Clegg

ฉันจะตรวจสอบgrantedพารามิเตอร์ในบล็อกการกรอกข้อมูลด้วย
cheesus

ฉันคิดว่าอาจมีข้อบกพร่องในรหัสนี้ หากฉันใช้พื้นหลังแอปของฉันไปที่การตั้งค่า -> ความเป็นส่วนตัว -> ผู้ติดต่อและเปิด / ปิดการอนุญาตแอปของฉันแอปของฉันจะหยุดทำงานทันที บางสิ่งจำเป็นต้องปล่อย? (ฉันไม่ได้ใช้ ARC)
AlBeebe

3
แก้ไข: นี่ไม่ใช่ข้อบกพร่อง แต่เป็นสิ่งที่ตั้งใจโดยระบบปฏิบัติการ ... stackoverflow.com/questions/12810638/…
AlBeebe

ขอขอบคุณที่พบว่า ฉันสังเกตเห็นพฤติกรรมนั้นเช่นกัน แต่ยังไม่ได้ย้อนกลับไปดูพื้นที่นั้นของโครงการนี้ "วิธีการใช้ค้อนขนาดใหญ่" ของ Apple นั้นน่าสนใจอย่างยิ่ง
Kyle Clegg

47

นั่นเป็นเคล็ดลับที่สมบูรณ์แบบสำหรับฉัน!

บน iOS6 แอปเปิลแนะนำการควบคุมความเป็นส่วนตัวใหม่ผู้ใช้สามารถควบคุมการเข้าถึงผู้ติดต่อและปฏิทินของแต่ละแอพได้ ดังนั้นในด้านรหัสคุณต้องเพิ่มวิธีการขออนุญาต ใน 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 จะขออนุญาตหากแอปไม่ได้ถามมาก่อน มิฉะนั้นจะเป็นไปตามการตั้งค่าใน Settings-Privacy-Contact

แหล่งที่มา: http://programmerjoe.blogspot.com/2012/10/ios6-permissions-contacts.html


ขอบคุณ Yunas ที่ทำการif (ABAddressBookRequestAccessWithCompletion != NULL)ตรวจสอบเพื่อควบคุมว่าจะเข้าสู่ABAddressBookGetAuthorizationStatus()ส่วนของรหัสของ Kyle หรือไม่ที่ทำงานได้ดีสำหรับฉันกับ iOS 5 และ 6
Ted

2
@Yunas แต่มันกำลังหยุดเธรดทั้งหมดฉันหมายถึงเมื่อการแจ้งเตือนปรากฏขึ้นเพื่อขอให้ผู้ใช้เข้าถึงรายชื่อปุ่มต่างๆไม่ตอบสนองแอพของฉันวางสายฉันเชื่อว่าเป็นเพราะ GCD dispatch_semaphore_wait
Eshwar Chaitanya

มีปัญหาบางอย่างกับรหัสของคุณใน Xcode5 Soveld มันและโพสต์การปรับปรุงด้านล่าง cheers
jerik

6

สำหรับกรอบการติดต่อ:

- (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;
    }
}

3
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"]];
    }
}

7
อาจเพิ่มข้อความเพื่อตอบคำถาม
user905686

3

มีปัญหาบางอย่างกับyunasโค้ดบน iOS6.1 ใน Xcode5 ด้วยการดัดแปลงเล็ก ๆ น้อย ๆมันได้ผลสำหรับฉัน

ปัญหาคือ ARC ใน iOS 6 ไม่อนุญาตให้ใช้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
  }
}

// ...

มีเพียงหน้าจอสีดำเท่านั้นที่ปรากฏขึ้นเหมือนแอพหยุดทำงานและเมื่อฉันปิดแอพฉันเห็นการแจ้งเตือนการอนุญาต คุณมีความคิดว่าเหตุใดจึงเกิดขึ้น การแจ้งเตือนนี้ควรอยู่ในแอปที่ไม่อยู่ในหน้าจอสีดำ
Yucel Bayram

2
- (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(@"=============================================");
    }
}

1

หากใครมีปัญหากับ addressBook ใน iOS5 ให้ใช้

ABAddressBookRef addressBook = ABAddressBookCreate(); 

ติดตั้งจาก

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL,NULL);

1
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!";


1

Swift 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)
    }
}

1

ตามเอกสารการพัฒนาแอปเปิ้ล iOS ที่ผ่านมาแอปเปิ้ลยืนยันที่จะใช้ติดต่อนอกเหนือจากสมุด

CNAuthorizationStatus authorizationStatus = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
    switch (authorizationStatus) {
        case CNAuthorizationStatusNotDetermined: {

            break;
        }
        case CNAuthorizationStatusRestricted: {

            break;
        }
        case CNAuthorizationStatusDenied:{

            return;
        }
            break;
        case CNAuthorizationStatusAuthorized: {

            break;
        }
    }

วัตถุประสงค์ข้างต้นรหัส c ช่วยในการค้นหาได้รับอนุญาตให้เข้าถึงการติดต่อสภาพอากาศหรือไม่


ทำงานได้อย่างมีเสน่ห์ขอบคุณ! .... เป็นเพียงจุดอ้างอิงสำหรับนักพัฒนารุ่นเยาว์ คุณต้องเข้าไปที่. xcodeproj -> general -> Frameworks, Libraries และ Embedded Contents ... จากนั้นเพิ่มรายการ 'Contacts.framework' (และอาจจะเป็น 'ContactsUI.framework' หากต้องการ)
เรือนกระจก

0

ด้วย iOS 6 คุณต้องขออนุญาตเช่นนี้

requestAccessToEntityType:EKEntityTypeEvent completion:

2
คำแนะนำของคุณใช้ได้กับการกระทำของ EventKit สิ่งที่เทียบเท่าสำหรับการเข้าถึง PhoneBook คือ ABAddressBookRequestAccessWithCompletion ขอบคุณที่พาฉันไปถูกทาง!
Kyle Clegg

คุณสามารถทำให้ ABAddressBookRequestAccessWithCompletion เป็นคำตอบที่ถูกต้องและยอมรับได้หรือไม่
Brian

0

เพื่อรับ Addressbook ใน 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];
}

}

0

รหัสนี้แสดงวิธีการตั้งค่าการอนุญาตและวิธีรับผู้ติดต่อทั้งหมดจากโทรศัพท์และแสดงรายชื่อในรายการพร้อมป้ายกำกับ

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()
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.