Адресная книга iOS 6 не работает? - программирование
Подтвердить что ты не робот

Адресная книга iOS 6 не работает?

Мой метод программного получения адресов электронной почты из адресной книги больше не работает на устройствах iOS 6. Он работал в iOS 5 и странно, все еще работает в iOS 6 Simulator. Есть ли новый способ программного извлечения контактов из адресной книги пользователей?

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

self.contacts = [[NSMutableArray alloc] init];

int contactIndex = 0;
for (int i = 0; i < nPeople; i++) {
    // Get the next address book record.
    ABRecordRef record = CFArrayGetValueAtIndex(allPeople, i);        

    // Get array of email addresses from address book record.
    ABMultiValueRef emailMultiValue = ABRecordCopyValue(record, kABPersonEmailProperty);
    NSArray *emailArray = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(emailMultiValue);

    [self.contacts addObject:emailArray];
}

Чтобы прояснить, вышесказанное не падает, оно просто не возвращает результатов. ABAddressBookCopyArrayOfAllPeople пуст. Спасибо!

4b9b3361

Ответ 1

Вероятно, связанный с новыми элементами управления конфиденциальности - с iOS 6, на устройстве, приложение не может обращаться к контактам пользователей без их разрешения. Из документации:

В iOS 6.0 и более поздних версиях, если вызывающий абонент не имеет доступа к База данных адресной книги:

• Для приложений, связанных с iOS 6.0 и более поздними версиями, эта функция возвращает NULL.

• Для приложений, связанных с предыдущей версией iOS, эта функция возвращает пустую базу данных только для чтения.

Если вы не заметили, что появилось предупреждение о разрешении ( "SomeApp хочет получить доступ к вашим контактам" ), возможно, что API-интерфейсы прямой адресной книги просто предполагают, что они не имеют доступа и молчат; вам может потребоваться отобразить что-то из структуры AddressBookUI, чтобы вызвать его.

Ответ 2

Я создал вспомогательный класс AddressBookHelper для обратной совместимости. Вот кишки:

-(BOOL)isABAddressBookCreateWithOptionsAvailable {
    return &ABAddressBookCreateWithOptions != NULL;
}

-(void)loadContacts {
    ABAddressBookRef addressBook;
    if ([self isABAddressBookCreateWithOptionsAvailable]) {
        CFErrorRef error = nil;
        addressBook = ABAddressBookCreateWithOptions(NULL,&error);
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
            // callback can occur in background, address book must be accessed on thread it was created on
            dispatch_async(dispatch_get_main_queue(), ^{
                if (error) {
                    [self.delegate addressBookHelperError:self];
                } else if (!granted) {
                    [self.delegate addressBookHelperDeniedAcess:self];
                } else {
                    // access granted
                    AddressBookUpdated(addressBook, nil, self);
                    CFRelease(addressBook);
                }
            });
        });
    } else {
        // iOS 4/5
        addressBook = ABAddressBookCreate();
        AddressBookUpdated(addressBook, NULL, self);
        CFRelease(addressBook);
    }
}

void AddressBookUpdated(ABAddressBookRef addressBook, CFDictionaryRef info, void *context) {
    AddressBookHelper *helper = (AddressBookHelper *)context;
    ABAddressBookRevert(addressBook);
    CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);

    // process the contacts to return
    NSArray *contacts = ...    

    [[helper delegate] addressBookHelper:helper finishedLoading:contacts];
};

Ответ 3

Попробуйте следующее: доступ к адресной книге должен быть предоставлен, прежде чем он сможет получить доступ программно. Вот что я сделал.

  #import <AddressBookUI/AddressBookUI.h>

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

  if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
    ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
      // First time access has been granted, add the contact
      [self _addContactToAddressBook];
    });
  }
  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
  }

Ответ 4

Вероятно, связанный с новыми элементами управления конфиденциальности, с iOS 6, на устройстве, приложение не может обращаться к контактам пользователей без их разрешения.

код:

-(void)addressBookValidation
{



NSUserDefaults *prefs=[NSUserDefaults standardUserDefaults];
ABAddressBookRef addressbook = ABAddressBookCreate();
__block BOOL accessGranted = NO;

if (ABAddressBookRequestAccessWithCompletion != NULL)
{
    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined)
    {
        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 if(ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized)
    {
        accessGranted = YES;
    }
    else if (ABAddressBookGetAuthorizationStatus()==kABAuthorizationStatusDenied)
    {
        accessGranted = NO;
    }
    else if (ABAddressBookGetAuthorizationStatus()==kABAuthorizationStatusRestricted){
        accessGranted = NO;
    }
    else
    {
        accessGranted = YES;
    }


}
else
{
    accessGranted = YES;
}
[prefs setBool:accessGranted forKey:@"addressBook"];

NSLog(@"[prefs boolForKey:@'addressBook']--->%d",[prefs boolForKey:@"addressBook"]);
[prefs synchronize];
CFRelease(addressbook);
}