我从地址簿中以编程方式检索电子邮件地址的方法似乎不再适用于iOS 6设备。它在iOS 5中工作,奇怪的是,仍然适用于iOS 6模拟器。是否有一种以编程方式从用户的地址簿中检索联系人的新方法?
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为空。谢谢!
答案 0 :(得分:52)
我创建了一个帮助类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];
};
答案 1 :(得分:12)
可能与新的隐私控制相关 - 从iOS 6开始,在设备上,应用无法在未经许可的情况下访问用户的联系人。来自文档:
在iOS 6.0及更高版本中,如果调用者无权访问 地址簿数据库:
•对于针对iOS 6.0及更高版本链接的应用,此函数返回NULL。
•对于与以前版本的iOS链接的应用,此函数返回一个空的只读数据库。
如果您还没有看到权限警报出现(“SomeApp希望访问您的联系人”),直接地址簿API可能只是假设他们没有访问权限而且无声地失败;您可能必须显示来自AddressBookUI框架的内容才能触发它。
答案 2 :(得分:12)
试试这个: 必须先授予对地址簿的访问权限,然后才能以编程方式进行访问。这就是我最终要做的事情。
#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
}
答案 3 :(得分:0)
可能与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);
}