iOS 6 地址簿不起作用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12517394/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS 6 Address Book not working?
提问by Keller
My method of programmatically retrieving e-mail addresses from the Address Book no longer seems to work on iOS 6 devices. It worked in iOS 5 and oddly, still works in the iOS 6 Simulator. Is there a new way to programmatically retrieve contacts from a users' Address Book?
我从通讯簿中以编程方式检索电子邮件地址的方法似乎不再适用于 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];
}
To clarify, the above does not crash, it simply returns no results. ABAddressBookCopyArrayOfAllPeople is empty. Thanks!
澄清一下,上面没有崩溃,它只是不返回任何结果。ABAddressBookCopyArrayOfAllPeople 为空。谢谢!
采纳答案by Noah Witherspoon
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. From the documentation:
可能与新的隐私控制有关——从 iOS 6 开始,在设备上,未经用户许可,应用程序无法访问用户的联系人。从文档:
On iOS 6.0 and later, if the caller does not have access to the Address Book database:
? For apps linked against iOS 6.0 and later, this function returns NULL.
? For apps linked against previous version of iOS, this function returns an empty read-only database.
在 iOS 6.0 及更高版本上,如果呼叫者无权访问地址簿数据库:
? 对于链接到 iOS 6.0 及更高版本的应用程序,此函数返回 NULL。
? 对于与以前版本的 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; you might have to display something from the AddressBookUI framework to trigger it.
如果您还没有看到权限警报出现(“SomeApp 想要访问您的联系人”),则可能是直接地址簿 API 只是假设它们没有访问权限并默默地失败;您可能需要显示 AddressBookUI 框架中的某些内容才能触发它。
回答by Christopher Pickslay
I created a helper class, AddressBookHelper
, to handle backward compatibility. Here are the guts:
我创建了一个辅助类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];
};
回答by Meet
Try with this: access to the address book must be grantedbefore 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
}
回答by anu
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);
}