在iOS 6中,以前工作正常的訪問通訊錄的iPhone程序可能會出錯,現象是程序啟動時不提醒用戶是否允許程序訪問通訊錄,同時在“設置->隱私->通訊錄”中看不到你的程序。另外,對通訊錄進行操作的代碼會報類似於以下消息的錯誤:
Could not compile statement for query (ABCCopyArrayOfAllInstancesOfClassInSourceMatchingProperties):
SELECT ROWID, Name, ExternalIdentifier, Type, ConstraintsPath, ExternalModificationTag, ExternalSyncTag, AccountID, Enabled, SyncData, MeIdentifier, Capabilities FROM ABStore WHERE Enabled = ?;
其原因是iOS 6加強了通訊錄訪問控制,要求開發人員顯式聲明需要訪問通訊錄,方法是調用 ABAddressBookRequestAccessWithCompletion
方法,具體參見官方文檔:
http://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-6_0/index.html
下面是對應的樣例代碼,一般來講需要將這段代碼放置在程序啟動部分,在程序啟動過程中提示用戶本程序需要訪問設備上的通訊錄:
ABAddressBookRef addressBook = ABAddressBookCreate();
__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) {
// we're on iOS 6
NSLog(@"on iOS 6 or later, trying to grant access permission");
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 { // we're on iOS 5 or older
NSLog(@"on iOS 5 or older, it is OK");
accessGranted = YES;
}
if (accessGranted) {
NSLog(@"we got the access right");
}