天天看点

iOS访问通讯录开发-读取联系人信息

读取通信录中的联系人一般的过程是先查找联系人记录,然后再访问记录的属性,属性又可以分为单值属性和多值属性。通过下面例子介绍联系人的查询,以及单值属性和多值属性的访问,还有读取联系人中的图片数据。

iOS访问通讯录开发-读取联系人信息

本案例是从ios设备上读取通讯录中的联系人,并将其显示在一个表视图中,可以进行查询,点击联系人进入详细信息画面。访问通讯录的应用必须要做的两件事情:

1、添加addressbook和addressbookui框架

为工程添加addressbook.framework和addressbookui.framework

iOS访问通讯录开发-读取联系人信息

2、引入头文件

在需要访问通讯录类的头文件中引入下面头文件:

#import <addressbook/addressbook.h>

#import <addressbookui/addressbookui.h>

在从通信录数据库查询联系人数据是无法使用sql语句,只能通过abaddressbookcopyarrayofallpeople和abaddressbookcopypeoplewithname函数获得,它们的定义如下:

abaddressbookcopyarrayofallpeople函数是查询所有的联系人数据。abaddressbookcopypeoplewithname函数是通过人名查询通讯录中的联系人,其中的name参数就是查询的前缀关键字。两个函数中都有addressbook参数,它是我们要查询的通讯录对象,其创建使用abaddressbookcreatewithoptions函数(在ios6之前是abaddressbookcreate函数),它的定义:

options参数是保留参数,目前没有采用,使用时候可以传递null值。error是错误对象,包含错误信息。

下面是我们代码中有关系查询的部分,先看一下viewcontroller.h:

属性listcontacts是装载联系人记录数组集合,filtercontentforsearchtext:方法是用来过滤联系人信息的方法,也就是查询方法。

viewcontroller.m中的viewdidload方法:

在viewdidload方法中首先在第①行代码处使用abaddressbookcreatewithoptions函数创建addressbook对象,然后在第②行又调用了函数abaddressbookrequestaccesswithcompletion,这个函数用于向用户请求访问通讯录数据库,如果是第一次访问,则会弹出一个用户授权对话框,如果用户授权可以访问则会调用下面的代码块。

由于请求和代码块的回调都是异步的,你会发现表视图画面先出现,然后过一会儿才有查询出来的结果。在ios6之后这个请求过程必须有的,否则无法访问通讯录数据库。

viewcontroller.m中的filtercontentforsearchtext:查询方法:

在该方法中实现查询,abaddressbookgetauthorizationstatus()函数返回应用的授权状态,其中kabauthorizationstatusauthorized常量代表用户已经授权,在没有授权情况下该方法不进行任何处理。abaddressbookcopyarrayofallpeople函数是查询所有数据,abaddressbookcopypeoplewithname函数是根据条件查询,返回值是cfarrayref类型,不能直接赋值给listcontacts(nsarray*类型)属性,处理方式一般如下两种:

self.listcontacts = (__bridge nsarray *)abaddressbookcopyarrayofallpeople(addressbook) ;

self.listcontacts = cfbridgingrelease(abaddressbookcopyarrayofallpeople(addressbook));

(__bridge nsarray *)方式不会转让对象所有权,只是简单强制转化。cfbridgingrelease函数实现的是core foundation类型到foundation类型转化并把对象所有权转让arc(自动管理引用计数),因此不需要释放属性listcontacts对应的成员变量。类似还有cfbridgingretain函数,实现的是foundation类型到core foundation类型转化, 并把对象所有权转让调用者,因此需要释放这个对象,代码如下:

最后在第④行调用cfrelease(addressbook)函数释放addressbook对象,core foundation框架中的数据类型内存管理是不受arc管理的,但是与foundation框架的mrc管理类似,需要手动释放,cfrelease函数就是相当于foundation框架中的release(或autorelease)方法。

viewcontroller.m中的searchbar查询相关方法:

#pragma mark –uisearchbardelegate 协议方法

在一条联系人记录中,有很多属性,这些属性有单值属性和多值属性,单值属性是只有一个值的属性,如:姓氏、名字等,它们是由下面常量定义的:

kabpersonfirstnameproperty,名字

kabpersonlastnameproperty,姓氏

kabpersonmiddlenameproperty,中间名

kabpersonprefixproperty,前缀

kabpersonsuffixproperty,后缀

kabpersonnicknameproperty,昵称

kabpersonfirstnamephoneticproperty,名字汉语拼音或音标

kabpersonlastnamephoneticproperty,姓氏汉语拼音或音标

q kabpersonmiddlenamephoneticproperty,中间名汉语拼音或音标

kabpersonorganizationproperty,组织名

kabpersonjobtitleproperty,头衔

kabpersondepartmentproperty,部门

kabpersonnoteproperty,备注

读取记录属性函数是abrecordcopyvalue,abrecordcopyvalue函数的定义如下:

abrecordref参数是记录对象,abpropertyid是属性id,就是上面的常量kabpersonfirstnameproperty等。返回值类型是cftyperef,它是core foundation类型的“泛型”,可以代表任何的core foundation类型。

viewcontroller.m中的tableview:cellforrowatindexpath:方法,主要实现了访问单值属性:

第①行abrecordref thisperson = cfbridgingretain([self.listcontacts objectatindex:[indexpath row]])语句是从nsarray*集合中取出一个元素,并且转化为core foundation类型的abrecordref类型。cfbridgingrelease(abrecordcopyvalue(thisperson, kabpersonfirstnameproperty))语句是将名字属性取出来,转化为nsstring*类型。最后cfrelease(thisperson)是释放abrecordref对象。

此外,为了把选中的联系人传递给详细画面,我们需要获得选中记录的id,然后把id传递到详细画面,这个过程处理是在viewcontroller.m中的 prepareforsegue:方法完成的:

其中第①行代码调用函数abrecordgetrecordid是获取选中记录的id,其中id为abrecordid类型。为了传递这个id给detailviewcontroller视图控制器,detailviewcontroller视图控制器定义了personidasnumber属性,在第③行将id给personidasnumber属性。detailviewcontroller.h代码如下:

#import <uikit/uikit.h>

@interface detailviewcontroller : uitableviewcontroller

@property (weak, nonatomic) iboutlet uiimageview *imageview;

@property (weak, nonatomic) iboutlet uilabel *lblname;

@property (weak, nonatomic) iboutlet uilabel *lblmobile;

@property (weak, nonatomic) iboutlet uilabel *lbliphone;

@property (weak, nonatomic) iboutlet uilabel *lblworkemail;

@property (weak, nonatomic) iboutlet uilabel *lblhomeemail;

@property (strong, nonatomic) nsnumber* personidasnumber;

@end

personidasnumber属性为nsnumber*类型。

多值属性是包含多个值的集合类型,如:电话号码、email、url等,它们主要是由下面常量定义的:

kabpersonphoneproperty,电话号码属性,kabmultistringpropertytype类型多值属性;

kabpersonemailproperty,email属性,kabmultistringpropertytype类型多值属性;

kabpersonurlproperty,url属性,kabmultistringpropertytype类型多值属性;

kabpersonrelatednamesproperty,亲属关系人属性,kabmultistringpropertytype类型多值属性;

kabpersonaddressproperty,地址属性,kabmultidictionarypropertytype类型多值属性;

kabpersoninstantmessageproperty,即时聊天属性,kabmultidictionarypropertytype类型多值属性;

kabpersonsocialprofileproperty,社交账号属性,kabmultidictionarypropertytype类型多值属性;

在多值属性中包含了label(标签)、value(值)和id等部分,其中标签和值都是可以重复的,而id是不能重复的

iOS访问通讯录开发-读取联系人信息

多值属性访问方式与单值属性访问类似都使用abrecordcopyvalue函数。不同的是多值属性访问返回值是abmultivalueref,然后要使用abmultivaluecopyarrayofallvalues函数从abmultivalueref对象中获取数组cfarrayref集合。abmultivaluecopyarrayofallvalues函数的定义如下:

参数multivalue是abmultivalueref对象,index是查找标签的索引。

abmultivaluegetidentifieratindex函数可以从abmultivalueref对象中返回id,其定义如下:

其中abmultivaluecopyarrayofallvalues(emailsproperty))语句是从emailsproperty属性中取出数组集合。kabworklabel和kabhomelabel都是email多值属性的标签。kabworklabel是工作email标签和kabhomelabel是家庭email标签,另外还有kabotherlabel,它是email标签。最后emailsproperty需要释放。

detailviewcontroller.m中的viewdidload方法中取得电话号码多值属性代码如下:

kabpersonphonemobilelabel和kabpersonphoneiphonelabel都是电话号码属性的标签。kabpersonphonemobilelabel是移动电话号码标签,kabpersonphoneiphonelabel是iphone电话号码标签。此外还有:

kabpersonphonemainlabel,主要电话号码标签;

kabpersonphonehomefaxlabel,家庭传真电话号码标签;

kabpersonphoneworkfaxlabel,工作传真电话号码标签;

kabpersonphonepagerlabel,寻呼机号码标签。

通讯录中的联系人可以有一个图片,读取联系人图片的相关函数有abpersoncopyimagedata和abpersonhasimagedata等。abpersoncopyimagedata可以读取联系人图片函数,它的定义如下:

它的返回类型是cfdataref,与之对应的foundation框架类型是nsdata*。abpersonhasimagedata函数用于判断联系人是否有图片,它的定义如下:

abpersoncopyimagedata取出的是cfdataref类型,将其转化为nsdata*,再使用uiimage的构造方法imagewithdata:构建uiimage对象,然后再把uiimage对象赋值给imageview图片控件。