简体   繁体   English

iOS 6地址簿无法正常工作?

[英]iOS 6 Address Book not working?

My method of programmatically retrieving e-mail addresses from the Address Book no longer seems to work on iOS 6 devices. 我从地址簿中以编程方式检索电子邮件地址的方法似乎不再适用于iOS 6设备。 It worked in iOS 5 and oddly, still works in the iOS 6 Simulator. 它在iOS 5中工作,奇怪的是,仍然适用于iOS 6模拟器。 Is there a new way to programmatically retrieve contacts from a users' Address Book? 有没有一种新方法以编程方式从用户的地址簿中检索联系人?

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

To clarify, the above does not crash, it simply returns no results. 为了澄清,上面没有崩溃,它只是没有返回任何结果。 ABAddressBookCopyArrayOfAllPeople is empty. ABAddressBookCopyArrayOfAllPeople为空。 Thanks! 谢谢!

I created a helper class, AddressBookHelper , to handle backward compatibility. 我创建了一个帮助类AddressBookHelper来处理向后兼容性。 Here are the guts: 这是胆量:

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

Probably related to the new privacy controls—as of iOS 6, on the device, an app can't access the user's contacts without their permission. 可能与新的隐私控制相关 - 从iOS 6开始,在设备上,应用无法在未经许可的情况下访问用户的联系人。 From the documentation: 从文档:

On iOS 6.0 and later, if the caller does not have access to the Address Book database: 在iOS 6.0及更高版本中,如果调用者无权访问通讯簿数据库:

• For apps linked against iOS 6.0 and later, this function returns NULL. •对于针对iOS 6.0及更高版本链接的应用程序,此函数返回NULL。

• For apps linked against previous version of iOS, this function returns an empty read-only database. •对于与先前版本的iOS链接的应用程序,此函数返回空的只读数据库。

If you haven't seen the permissions alert come up (“SomeApp would like access to your contacts”), it's possible that the direct address-book APIs just assume that they don't have access and silently fail; 如果您还没有看到权限警报出现(“SomeApp希望访问您的联系人”),直接地址簿API可能只是假设他们没有访问权限并且无声地失败; you might have to display something from the AddressBookUI framework to trigger it. 您可能必须显示AddressBookUI框架中的某些内容才能触发它。

Try with this: access to the address book must be granted before it can be access programmatically. 试试这个: 必须先授予对地址簿的访问权限,然后才能以编程方式进行访问。 Here is what I ended up doing. 这就是我最终做的事情。

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

Probably related to the new privacy controls, as of iOS 6, on the device, an app can't access the user's contacts without their permission. 可能与设备上的新隐私控制(如iOS 6)相关,应用无法在未经其许可的情况下访问用户的联系人。

Code: 码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM