不同iOS系统版本下ABPeoplePickerNavigationController和ABAddressBook访问系统通讯录的区别

来源:互联网 发布:行知天下参考答案2017 编辑:程序博客网 时间:2024/04/28 11:20

1、ABAddressBook

1、在ios6之前,访问系统通讯录是不需要征得用户同意的,访问通讯录的方法如下所示:
ABAddressBookRef ABAddressBookCreate ( void ),返回一个包含通讯录信息的ABAddressBookRef实例
在ios6(包括)ios6之后,访问系统通讯录是需要征的用户同意的,访问通讯录的方法也改变了,方法如下所示:
ABAddressBookRef ABAddressBookCreateWithOptions ( CFDictionaryRef options, CFErrorRef *error);
具体的视线可以参考我写的代码:
代码补充说明:
[按照网上所属,block里面的方法是只有在用户成功授权的情况下,才会走,不过我写了demo去测试,发现,无论用户同不同意授权,block都会调用,信号量都会加1,程序会继续向下进行]。
如果用户同意,则 CFArrayRef results =  ABAddressBookCopyArrayOfAllPeople(addressBook)方法返回的结果就是系统通讯录的copy;
如果用户不同意,CFArrayRef results =  ABAddressBookCopyArrayOfAllPeople(addressBook)返回的结果是空的。
为了安全判断,如下代码所示,我在copy通讯录信心前又加了安全判断,判断用户是否成功授权。
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
        
if ([UIDevice currentDevice].systemVersion.floatValue >= 6.0) {
            addressBook = 
ABAddressBookCreateWithOptions(NULLNULL);
            
//发出访问通讯录的请求
            
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error){
                
//信号量加1
                
dispatch_semaphore_signal(sema);
            });
            
//如果信号量仍未0,则等待,知道得到用户的授权
            
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
        }
else{
            
//ios6之前的方法
            addressBook = 
ABAddressBookCreate();
        }
        #warnging
        
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
            
CFArrayRef results =  ABAddressBookCopyArrayOfAllPeople(addressBook);
            
long peopleCount = CFArrayGetCount(results);
            
if (peopleCount >= 0) {
                [
self presentABPeopleNav];
            }
        }
    }
   2、ABPeoplePickerNavigationController


ABPeoplePickerNavigationController的使用就和UIImagePickerViewController的使用是一样的。
在ios8之前需要需要用户授权,授权成功之后才可以访问
但是在ios8之后,不会提示用户是否授权,可以直接访问
苹果官方文档解释如下所示:

In iOS 8 and later bringing up a people-picker navigtion controller does not require the app to have access to a user’s contacts, and the user will not be prompted to grant access. If the app does not itself have access to the user’s contacts, a temporary copy of the contact selected by the user will be returned to the app.

ABPeoplePickerNavigationController也有对应的代理方法,可以实现用户对通讯录的操作。要注意的时,ios7和ios8使用的代理方法是有区别的。ios8下会有意想不到的bug,到目前为止遇到了两个:
第一个bug:进入到信息人详情页后,会突然dismiss
解决办法是:
在实例化ABPeoplePickerNavigationController时,加上下面的代码
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0){
        
//点击联系人跳转到联系人详情界面
        peoplePicker.
predicateForSelectionOfPerson = [NSPredicate predicateWithValue:FALSE];//防止进入详情页的时候突然dismissios8bug
    }

第二个bug:点击联系电话时,跳转到了拨打电话的界面
bug原因是:ios7和ios8下要实现的代理方法是不同的
解决办法是:stackoverflow网站的建议如下:
意思就是如果是ios8,就是在ios的代理方法中调用ios7下的代理方法

Keep the old delegate method in place to support iOS 7 or earlier. What I do in my app is call the iOS 7 delegate method from the iOS 8 delegate method:

- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {    [self peoplePickerNavigationController:peoplePicker shouldContinueAfterSelectingPerson:person property:property identifier:identifier];}

0 0
原创粉丝点击