Fordern Sie programmgesteuert den Zugriff auf Kontakte an


109

Seit dem Update auf iOS 6 ist mir aufgefallen, dass mein Code zum Hinzufügen eines Kontakts zum Adressbuch des iPhones nicht mehr funktioniert. Ich glaube, dies ist ein Problem im Zusammenhang mit Berechtigungen, da Apple jetzt Benutzerberechtigungen benötigt, bevor auf Kontakte zugegriffen werden kann (Behebung dieses Problems) Problems).

Ich habe erwartet, dass die App automatisch um Erlaubnis bittet, auf Kontakte zuzugreifen, wie im folgenden Screenshot, aber das tut sie nicht. Der Versuch, den Kontakt hinzuzufügen, schlägt mit einfach fehlABAddressBookErrorDomain error 1 .

Muss ich den Zugriff auf den Kontaktanforderungsdialog programmgesteuert starten? Wie geht das?

auf Kontakte zugreifen

Antworten:


180

Gemäß dieser Dokumentation auf der Apple-Website (scrollen Sie nach unten zu Datenschutz in der Mitte der Seite) muss der Zugriff auf das Adressbuch gewährt werden, bevor programmgesteuert darauf zugegriffen werden kann. Hier ist, was ich letztendlich getan habe.

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

Update für iOS 9 und höher:

Von der Apple-Website:

Wichtig

Das Adressbuch-UI-Framework ist in iOS 9 veraltet. Verwenden Sie stattdessen die im ContactsUI-Framework definierten APIs. Weitere Informationen finden Sie unter ContactsUI


Meine Antwort wurde bearbeitet, um den Import einzuschließen. Beachten Sie, dass Sie auch die Frameworks AddressBook und AddressBookUI auf der Registerkarte Build-Phasen mit Ihrem Projekt verknüpfen müssen.
Kyle Clegg

Ich würde auch den grantedParameter im Abschlussblock überprüfen .
Cheesus

Ich denke, es könnte einen Fehler in diesem Code geben. Wenn ich meine App im Hintergrund habe, gehe zu Einstellungen-> Datenschutz-> Kontakte und schalte meine App-Berechtigung ein / aus. Meine App stürzt sofort ab. Muss etwas freigegeben werden? (
Ich benutze

3
EDIT: Dies ist kein Fehler, es ist eigentlich eine absichtliche Sache des Betriebssystems ... stackoverflow.com/questions/12810638/…
AlBeebe

Danke, dass du das herausgefunden hast. Ich bemerkte dieses Verhalten auch, hatte mich aber noch nicht wieder mit diesem Bereich dieses Projekts befasst. Apples "Vorschlaghammer-Ansatz" ist in der Tat interessant.
Kyle Clegg

47

Das war der perfekte Trick für mich!

Unter iOS6 führt Apple eine neue Datenschutzkontrolle ein. Der Benutzer kann den Zugriff auf Kontakt und Kalender für jede App steuern. Auf der Codeseite müssen Sie also eine Möglichkeit hinzufügen, um die Berechtigung anzufordern. In iOS5 oder früher können wir immer anrufen

ABAddressBookRef addressBook = ABAddressBookCreate();

Um das Adressbuch ohne Probleme zu erhalten, aber in iOS6, wenn Sie keine Berechtigung haben, gibt dieser Aufruf nur einen leeren Zeiger zurück. Deshalb müssen wir die Methode ändern, um ABAddressBookRef zu erhalten.

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

Im Code wird das Semaphor zum Blockieren bis zur Antwort verwendet, während ABAddressBookRequestAccessWithCompletion um Erlaubnis bittet, wenn die App zuvor nicht gefragt hat. Andernfalls folgen Sie einfach den Einstellungen in Einstellungen-Datenschutz-Kontakt.

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


Vielen Dank an Yunas, der if (ABAddressBookRequestAccessWithCompletion != NULL)überprüft hat, ob er in den ABAddressBookGetAuthorizationStatus()Abschnitt von Kyles Code gehen soll. Das hat bei iOS 5 und 6 gut funktioniert.
Ted

2
@Yunas Aber es ist , alle Fäden zu stoppen, ich meine , wenn der Alarm Benutzer auffordert , erscheint auf ihre Kontakte zugreifen, die Tasten sind nicht ansprechbar, meine app auflegt, ich glaube , es ist wegen der GCD dispatch_semaphore_wait
Eshwar Chaitanya

hatte einige Probleme mit Ihrem Code in Xcode5. Soveld es und postete das Update unten . Prost
Jerik

6

Für den Kontaktrahmen:

- (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
Fügen Sie möglicherweise einen Text hinzu, um die Fragen zu beantworten.
user905686

3

Hatte einige Probleme mit Yunas- Code unter iOS6.1 in Xcode5. Mit ein paar kleinen Anpassungen hat es bei mir funktioniert.

Das Problem war, dass ARC in iOS 6 dies nicht zulässt. dispatch_release(sema);Hier ist der Arbeitscode. Hinweis: Ich verwende m_addressbookstatt addressbookals 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
  }
}

// ...

Es erscheint nur ein schwarzer Bildschirm, als wäre die App eingefroren, und wenn ich die App schließe, wird eine Benachrichtigung über die Erlaubnis angezeigt. Haben Sie eine Idee, warum es passiert? Diese Warnung sollte in der App nicht unter einem schwarzen Bildschirm angezeigt werden.
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

Wenn jemand ein Problem mit dem Adressbuch in iOS5 hat, verwenden Sie

ABAddressBookRef addressBook = ABAddressBookCreate(); 

Anstelle von

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

Zum Hinzufügen einer Beschreibung zur Warnung verwenden Sie InfoPlist.strings.

NSContactsUsageDescription = "TESTING!";


1

Swift 3. Vergessen Sie nicht, Kontakte zu importieren

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

Laut der jüngsten Apple-Entwicklungsdokumentation für iOS besteht Apple darauf, neben AddressBook auch Contact zu verwenden .

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

            break;
        }
        case CNAuthorizationStatusRestricted: {

            break;
        }
        case CNAuthorizationStatusDenied:{

            return;
        }
            break;
        case CNAuthorizationStatusAuthorized: {

            break;
        }
    }

Der oben genannte Ziel-C-Code hilft beim Auffinden, ob die Berechtigung zum Zugriff auf Wetterkontakte erteilt wurde oder nicht.


funktioniert wie ein Zauber danke! .... nur ein Bezugspunkt für Junior-Entwickler. Sie müssen zu .xcodeproj -> general -> Frameworks, Libraries und Embedded Contents gehen und dann das Element 'Contacts.framework' (und gegebenenfalls auch 'ContactsUI.framework') hinzufügen
Gewächshaus

0

Unter iOS 6 müssen Sie um Erlaubnis bitten

requestAccessToEntityType:EKEntityTypeEvent completion:

2
Ihr Vorschlag funktioniert für die EventKit-Aktion. Das Äquivalent für den Zugriff auf das Telefonbuch ist ABAddressBookRequestAccessWithCompletion. Danke, dass du mich auf den richtigen Weg gebracht hast!
Kyle Clegg

Kann einer von Ihnen ABAddressBookRequestAccessWithCompletion zur richtigen Antwort machen und akzeptieren?
Brian

0

Adressbuch in ios bekommen

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

Dieser Code zeigt, wie Sie die Berechtigung festlegen und alle Kontakte vom Telefon abrufen und die Kontakte in der Liste mit dem Label-Tag anzeigen

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()
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.