[ios] 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<peopleCount; 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<phoneCount; 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();

时间: 2024-12-22 14:27:03

[ios] ios6 ios7 访问和使用系统通讯录的相关文章

iOS开发--系统通讯录的访问与添加联系人

公司项目有访问通讯录的需求,所以开始了探索之路.从开始的一无所知,到知识的渐渐清晰.这一切要感谢广大无私分享的 “coder”,注:我是尊称的语气! 苹果提供了访问系统通讯录的框架,以便开发者对系统通讯录进行操作.(此demo为纯代码),想要访问通讯录,需要添加AddressBookUI.framework和AddressBook.framework两个框架,添加的地点这里就不在赘述了.在控制器内部首先import两个头文件,<AddressBook/AddressBook.h> 和 <

iOS -------- 应用程序引用系统通讯录

转自:http://www.cnblogs.com/ygm900/p/3472288.html 由于ios系统对用户隐私的控制,第三方应用程序只能通过苹果官方接口调用系统通讯录,不能像android那样直接操作通讯录数据库.     一般地,使用系统自带通讯录的方法有两种,一种是直接将整个通讯录引入到应用程序,另一种是逐条读取通讯录中的每一条联系人信息.下面我们就一一详解. 1 直接引用整个通讯录 使用的类:ABPeoplePickerNavigationController方法: 在Local

IOS获取系统通讯录联系人信息

先导入AddressBook.framework先 然后引用  #import <AddressBook/AddressBook.h> 一.权限注册 随着apple对用户隐私的越来越重视,IOS系统的权限设置也更加严格,在获取系统通讯录之前,我们必须获得用户的授权.权限申请代码示例如下: #pragma mark - 注册权限 - (void)contacts { //这个变量用于记录授权是否成功,即用户是否允许我们访问通讯录 int __block tip = 0; //声明一个通讯簿的引用

iOS:ABPeoplePickerNavigationController系统通讯录使用

昨天因项目需求要访问系统通讯录获取电话号码,于是乎从一无所知,开始倒腾,倒腾了一下午,总算了弄好了.写这边博客是为了记录一下,自己下一次弄的时候就别在出错了.同时,有和我一样的菜鸟能够避免走一下弯路. 好了,言归正传,要访问系统的通讯录,首先需要添加AddressBook.framework和AddressBookUI.framework两个框架到你工程中build phase的"Link Binary With Libraries"之下,然后就可以开始了. 首先我们需要创建一个控制器

iOS开发之系统通讯录

@iOS调用操作通讯录所用的库文件 AddressBook.framework AddressBookUI.framework #import "HMTMainViewController.h" #import <AddressBook/AddressBook.h> #import <AddressBookUI/AddressBookUI.h> @interface HMTMainViewController ()<ABPeoplePickerNaviga

iOS --调用系统通讯录

// 调用系统通讯录需要遵循两个代理ABPeoplePickerNavigationControllerDelegate,UINavigationControllerDelegate 相关类为ABPeoplePickerNavigationController // 系统通讯录自带导航栏,所有要model出来 // 初始化 ABPeoplePickerNavigationController *peoplePicker = [[ABPeoplePickerNavigationController

iOS开发--调用系统通讯录界面

今天写代码遇到了要调用系统通讯录,看了一些博客发现写的都是获取通讯录的内容,而不是调用系统的界面. 分享一下自己写的代码 第一步:引入 #import <AddressBook/AddressBook.h> #import <AddressBookUI/AddressBookUI.h> 第二步:添加点击事件 创建一个通讯录界面 并以present的方式跳转 #pragma mark -- IBAction - (IBAction)buttonClicked:(id)sender {

IOS 获取系统通讯录

进入正题  获取系统通讯录,不想多讲,留下链接http://my.oschina.net/joanfen/blog/140146 通常做法: 首先创建一个ABAddressBookRef类的对象addressBooks,然后获取系统权限, 获取权限的代码: // 获取系统权限,并获得通讯录内容存入addressBooks. ABAddressBookRef addressBooks = nil; addressBooks = ABAddressBookCreateWithOptions(NULL

汇总一下iOS6,iOS7的新特性

汇总一下iOS6,iOS7的新特性时间 2014-02-01 23:07:48  CSDN博客原文  http://blog.csdn.net/ioswyl88219/article/details/18896657主题 iOS开发iOS6新特性 每次ios大版本的更新,都会带来一些新的东西,对开发者来说,有利有弊. 好处是,新增了很多新的属性,控件和api,开发者权限更大了,可以轻松实现更多的功能.弊端在于,可能废除了一些旧的api接口,需要做更多的适配和兼容.通过自己开发过程中的一些经验,查