programing

프로그래밍 방식으로 연락처 액세스 요청

lastcode 2023. 6. 11. 10:42
반응형

프로그래밍 방식으로 연락처 액세스 요청

iOS 6로 업데이트한 이후 아이폰의 주소록에 연락처를 추가하는 코드가 더 이상 작동하지 않습니다.애플은 이제 연락처에 접근하기 전에 사용자 권한을 요구하기 때문에 (이 문제를 해결하기 위해) 이것은 권한과 관련된 문제라고 생각합니다.

아래 스크린샷처럼 앱이 자동으로 연락처 접근 권한을 요청할 것으로 예상했지만 그렇지 않습니다.연락처를 추가하려고 하면 실패합니다.ABAddressBookErrorDomain error 1.

연락처 요청 대화 상자에 대한 액세스를 프로그래밍 방식으로 시작해야 합니까?어떻게 하는 거지?

연락처 액세스

Apple 사이트의 이 문서(페이지 중앙의 개인 정보로 스크롤)에 따라 주소록에 대한 액세스 권한이 부여되어야만 프로그래밍 방식으로 액세스할 수 있습니다.이것이 제가 결국 하게 된 일입니다.

  #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 사용대신 UI 프레임워크가 필요로 합니다.자세한 내용은 연락처를 참조하십시오.UI

그것은 나에게 완벽한 속임수였습니다!

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은 앱이 이전에 묻지 않은 경우 권한을 요청합니다.그렇지 않으면 [설정] - [개인 정보] - [연락처]의 설정만 따릅니다.

출처: http://programmerjoe.blogspot.com/2012/10/ios6-permissions-contacts.html

연락처 프레임워크의 경우:

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

Xcode5의 iOS6.1에서 yunas 코드에 약간의 문제가 있었습니다.약간의 작은 적응으로 그것은 저에게 효과가 있었습니다.

문제는 iOS 6의 ARC가 허용하지 않는다는 것이었습니다.dispatch_release(sema);여기 작업 코드가 있습니다.참고: 사용합니다.m_addressbook대신에addressbookAB 주소록 참조로!

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

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

iOS의 최근 애플 개발 문서에 따르면, 애플은 주소록 에 Contact를 사용해야 한다고 주장합니다.

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

            break;
        }
        case CNAuthorizationStatusRestricted: {

            break;
        }
        case CNAuthorizationStatusDenied:{

            return;
        }
            break;
        case CNAuthorizationStatusAuthorized: {

            break;
        }
    }

위의 목표 ccode는 날씨 연락처 액세스 권한이 부여되었는지 여부를 확인하는 데 도움이 됩니다.

iOS5에서 addressBook에 문제가 있는 사람이 있다면,

ABAddressBookRef addressBook = ABAddressBookCreate(); 

대신

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL,NULL);
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!";

스위프트 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)
    }
}

iOS 6에서는 다음과 같이 권한을 요청해야 합니다.

requestAccessToEntityType:EKEntityTypeEvent completion:

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

}

이 코드는 권한을 설정하는 방법과 전화기에서 모든 연락처를 가져오고 목록에 있는 연락처를 레이블 태그와 함께 표시하는 방법을 보여줍니다.

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

언급URL : https://stackoverflow.com/questions/12648244/programmatically-request-access-to-contacts

반응형