ios6 ios7 访问和使用系统通讯录权限

 ios6 ios7 访问和使用系统通讯录

导入AddressBook和AddressBookUI框架

iOS 6之前,可以通过如下方法获得通讯录 
ABAddressBookRef addressBook = ABAddressBookCreate();  

不过在iOS 6之后,这个方法被废弃,可以使用下面的方法获得通讯录。

AB_EXTERN ABAddressBookRef ABAddressBookCreateWithOptions(CFDictionaryRef options, CFErrorRef* error) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);  


而且在ios6之后,每个App要访问通讯录都应该得到用户的授权:

//系统定义的block

typedef void(^ ABAddressBookRequestAccessCompletionHandler) (bool granted, CFErrorRef error);  




//获取授权的方法,其中第二个参数是上面定义的block


AB_EXTERN void ABAddressBookRequestAccessWithCompletion(ABAddressBookRef addressBook,   ABAddressBookRequestAccessCompletionHandler  completion) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);  


代码如下:
-(void)getAddress
{
//typedef CFTypeRef ABAddressBookRef;
//typedef const void * CFTypeRef;
//指向常量的指针
ABAddressBookRef addressBook = nil;
//判断当前系统的版本
if ([[UIDevice currentDevice].systemVersion floatValue] >= 6.0)
{
//如果不小于6.0,使用对应的api获取通讯录,注意,必须先请求用户的同意,如果未获得同意或者用户未操作,此通讯录的内容为空
addressBook = ABAddressBookCreateWithOptions(NULL, NULL);//等待同意后向下执行//为了保证用户同意后在进行操作,此时使用多线程的信号量机制,创建信号量,信号量的资源数0表示没有资源,调用dispatch_semaphore_wait会立即等待。若对此处不理解,请参看GCD信号量同步相关内容。
dispatch_semaphore_t sema = dispatch_semaphore_create(0);//发出访问通讯录的请求
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error){
//如果用户同意,才会执行此block里面的方法
//此方法发送一个信号,增加一个资源数
dispatch_semaphore_signal(sema);});
//如果之前的block没有执行,则sema的资源数为零,程序将被阻塞
//当用户选择同意,block的方法被执行, sema资源数为1;
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);
}
    //如果系统是6.0之前的系统,不需要获得同意,直接访问

    else{  

addressBook = ABAddressBookCreate(); 

    }
    
//通讯录信息已获得,开始取出
CFArrayRef results = ABAddressBookCopyArrayOfAllPeople(addressBook);
//联系人条目数(使用long而不使用int是为了兼容64位)
long peopleCount = CFArrayGetCount(results);
for (int i=0; i {
ABRecordRef record = CFArrayGetValueAtIndex(results, i);
NSString *firstName,*lastName;


firstName = nil;
lastName= nil;


CFTypeRef tmp = NULL;
//firstName
tmp = ABRecordCopyValue(record, kABPersonFirstNameProperty);
if (tmp) {
firstName = [NSString stringWithString:tmp];
CFRelease(tmp);tmp = NULL;
}
//lastName
tmp = ABRecordCopyValue(record, kABPersonLastNameProperty);
if (tmp){
lastName= [NSString stringWithString:tmp];
CFRelease(tmp);
tmp = NULL;
}
//取得完整名字(与上面firstName、lastName无关)
 CFStringRef  fullName=ABRecordCopyCompositeName(record);
NSLog(@"%@",(NSString*)fullName);
// 读取电话,不只一个
ABMultiValueRef phones = ABRecordCopyValue(record, kABPersonPhoneProperty);
long phoneCount = ABMultiValueGetCount(phones);
for (int j=0; j // label
CFStringRef lable = ABMultiValueCopyLabelAtIndex(phones, j);
// phone number
CFStringRef number = ABMultiValueCopyValueAtIndex(phones, j);
// localize label
CFStringRef local = ABAddressBookCopyLocalizedLabel(lable);
//此处可使用一个自定义的model类来存储姓名和电话信息。我在这里就直接输出了。
NSLog(@"number%@" ,(NSString *)number);
if (local)CFRelease(local);
if (lable) CFRelease(lable);
if (number)CFRelease(number);
}
if (phones) CFRelease(phones);
record = NULL;
}
if (results)CFRelease(results);
    results = nil;
    if (addressBook)CFRelease(addressBook);
        addressBook = NULL;
}


请求访问通讯录,不过这只会在第一次请求授权时才显示对话框,如果用户已经拒绝了,我们可以判断下授权状态:
通过判断授权状态,我们可以再次提醒用户进行授权。
typedef CF_ENUM(CFIndex, ABAuthorizationStatus) {      
    kABAuthorizationStatusNotDetermined = 0,      
    kABAuthorizationStatusRestricted,      
    kABAuthorizationStatusDenied,      
    kABAuthorizationStatusAuthorized  
};  


AB_EXTERN ABAuthorizationStatus ABAddressBookGetAuthorizationStatus(void) __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);  


//获得状态,根据状态判断
ABAuthorizationStatus statu=ABAddressBookGetAuthorizationStatus(); 


调试经验分享:一般程序安装后,第一次会提示是否访问XXXX,再到二次的时候不管怎么它都不会提示,这样就不方便大家的调试了!
在设备里面还原后,它就会再次出现!
还原步棸:
设置--》通用--》还原--》还原位置与隐私
ok就可以了!系统将清除保存应用的访问权限设置。

你可能感兴趣的:(iOS开发)