アドレス帳からプログラムで電子メールアドレスを取得する私の方法は、iOS6デバイスでは機能しなくなったようです。これはiOS5で機能し、奇妙なことに、iOS6シミュレーターでも機能します。ユーザーのアドレス帳から連絡先をプログラムで取得する新しい方法はありますか?
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は空です。ありがとう!
おそらく新しいプライバシーコントロールに関連しています。iOS6以降、デバイスでは、アプリはユーザーの連絡先にユーザーの許可なしにアクセスできません。ドキュメントから:
IOS 6.0以降で、発信者がアドレス帳データベースにアクセスできない場合:
•iOS6.0以降に対してリンクされているアプリの場合、この関数はNULLを返します。
•以前のバージョンのiOSに対してリンクされたアプリの場合、この関数は空の読み取り専用データベースを返します。
権限アラートが表示されない場合(「SomeAppが連絡先へのアクセスを希望しています」)、直接アドレス帳APIは、アクセス権がないと想定してサイレントに失敗する可能性があります。それをトリガーするために、AddressBookUIフレームワークから何かを表示しなければならない場合があります。
下位互換性を処理するために、ヘルパークラス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];
};
これを試してみてください:プログラムでアクセスする前に、アドレス帳へのアクセス許可する必要があります。これが私がやったことです。
#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
}
おそらく、デバイス上の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);
}