在iOS 6中,以前工作正常的訪(fǎng)問(wèn)通訊錄的iPhone程序可能會(huì )出錯,現象是程序啟動(dòng)時(shí)不提醒用戶(hù)是否允許程序訪(fǎng)問(wèn)通訊錄,同時(shí)在“設置->隱私->通訊錄”中看不到你的程序。另外,對通訊錄進(jìn)行操作的代碼會(huì )報類(lèi)似于以下消息的錯誤:
[plain] view plaincopy
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加強了通訊錄訪(fǎng)問(wèn)控制,要求開(kāi)發(fā)人員顯式聲明需要訪(fǎng)問(wèn)通訊錄,方法是調用 ABAddressBookRequestAccessWithCompletion
方法,具體參見(jiàn)官方文檔:
http://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-6_0/index.html
下面是對應的樣例代碼,一般來(lái)講需要將這段代碼放置在程序啟動(dòng)部分,在程序啟動(dòng)過(guò)程中提示用戶(hù)本程序需要訪(fǎng)問(wèn)設備上的通訊錄:
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");