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

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




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

 

1

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

1、添加AddressBook和AddressBookUI框架

为工程添加AddressBook.framework和AddressBookUI.framework

 

2

2、引入头文件

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

#import <AddressBook/AddressBook.h>

#import <AddressBookUI/AddressBookUI.h>

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

[cpp]  FArrayRef ABAddressBookCopyArrayOfAllPeople ( 
 
ABAddressBookRef addressBook 
 
); 
 
CFArrayRef ABAddressBookCopyPeopleWithName ( 
 
ABAddressBookRef addressBook, 
 
CFStringRef name 
 
); 

CFArrayRef ABAddressBookCopyArrayOfAllPeople (

ABAddressBookRef addressBook

);

CFArrayRef ABAddressBookCopyPeopleWithName (

ABAddressBookRef addressBook,

CFStringRef name

);


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

[cpp]  ABAddressBookRef ABAddressBookCreateWithOptions ( 
 
CFDictionaryRef options, 
 
CFErrorRef* error 
 
); 

ABAddressBookRef ABAddressBookCreateWithOptions (

CFDictionaryRef options,

CFErrorRef* error

);


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

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

[cpp]
#import <UIKit/UIKit.h>  
 
#import <AddressBook/AddressBook.h>  
 
#import ”DetailViewController.h”  
 
@interface ViewController : UITableViewController 
 
<UISearchBarDelegate, UISearchDisplayDelegate> 
 
@property (nonatomic, strong) NSArray *listContacts; 
 
- (void)filterContentForSearchText:(NSString*)searchText; 
 
@end 

#import <UIKit/UIKit.h>

#import <AddressBook/AddressBook.h>

#import ”DetailViewController.h”

@interface ViewController : UITableViewController

<UISearchBarDelegate, UISearchDisplayDelegate>

@property (nonatomic, strong) NSArray *listContacts;

- (void)filterContentForSearchText:(NSString*)searchText;

@end


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

ViewController.m中的viewDidLoad方法:

[cpp]
- (void)viewDidLoad 
 

 
[super viewDidLoad]; 
 
CFErrorRef error = NULL; 
 
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); ① 
 
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { ② 
 
if (granted) { 
 
//查询所有  
 
[self filterContentForSearchText:@""];  ③ 
 

 
}); 
 
CFRelease(addressBook);  ④ 
 

- (void)viewDidLoad

{

[super viewDidLoad];

CFErrorRef error = NULL;

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); ①

ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { ②

if (granted) {

//查询所有

[self filterContentForSearchText:@""];  ③

}

});

CFRelease(addressBook);  ④

}


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

[cpp]
^(bool granted, CFErrorRef error) { 
 
if (granted) { 
 

 
}); 

^(bool granted, CFErrorRef error) {

if (granted) {

}

});


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

ViewController.m中的filterContentForSearchText:查询方法:

[cpp]
- (void)filterContentForSearchText:(NSString*)searchText 
 

 
//如果没有授权则退出  
 
if (ABAddressBookGetAuthorizationStatus() != kABAuthorizationStatusAuthorized) { 
 
return ; 
 

 
CFErrorRef error = NULL; 
 
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); 
 
if([searchText length]==0) 
 

 
//查询所有  
 
self.listContacts = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook)); 
 
} else { 
 
//条件查询  
 
CFStringRef cfSearchText = (CFStringRef)CFBridgingRetain(searchText); 
 
self.listContacts = CFBridgingRelease(ABAddressBookCopyPeopleWithName(addressBook, cfSearchText)); 
 
CFRelease(cfSearchText); 
 

 
[self.tableView reloadData]; 
 
CFRelease(addressBook); 
 

- (void)filterContentForSearchText:(NSString*)searchText

{

//如果没有授权则退出

if (ABAddressBookGetAuthorizationStatus() != kABAuthorizationStatusAuthorized) {

return ;

}

CFErrorRef error = NULL;

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);

if([searchText length]==0)

{

//查询所有

self.listContacts = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));

} else {

//条件查询

CFStringRef cfSearchText = (CFStringRef)CFBridgingRetain(searchText);

self.listContacts = CFBridgingRelease(ABAddressBookCopyPeopleWithName(addressBook, cfSearchText));

CFRelease(cfSearchText);

}

[self.tableView reloadData];

CFRelease(addressBook);

}


在该方法中实现查询,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类型转化, 并把对象所有权转让调用者,因此需要释放这个对象,代码如下:

[cpp]
CFStringRef cfSearchText = (CFStringRef)CFBridgingRetain(searchText); 
 
self.listContacts = CFBridgingRelease(ABAddressBookCopyPeopleWithName(addressBook, cfSearchText)); 
 
CFRelease(cfSearchText); 

CFStringRef cfSearchText = (CFStringRef)CFBridgingRetain(searchText);

self.listContacts = CFBridgingRelease(ABAddressBookCopyPeopleWithName(addressBook, cfSearchText));

CFRelease(cfSearchText);


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

ViewController.m中的SearchBar查询相关方法:

#pragma mark –UISearchBarDelegate 协议方法

[cpp]
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar 
 

 
//查询所有  
 
[self filterContentForSearchText:@""]; 
 

 
#pragma mark - UISearchDisplayController Delegate Methods  
 
//当文本内容发生改变时候,向表视图数据源发出重新加载消息  
 
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller 
 
shouldReloadTableForSearchString:(NSString *)searchString 
 

 
[self filterContentForSearchText:searchString]; 
 
//YES情况下表视图可以重新加载  
 
return YES; 
 

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar

{

//查询所有

[self filterContentForSearchText:@""];

}

#pragma mark - UISearchDisplayController Delegate Methods

//当文本内容发生改变时候,向表视图数据源发出重新加载消息

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller

shouldReloadTableForSearchString:(NSString *)searchString

{

[self filterContentForSearchText:searchString];

//YES情况下表视图可以重新加载

return YES;

}


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

kABPersonFirstNameProperty,名字

kABPersonLastNameProperty,姓氏

kABPersonMiddleNameProperty,中间名

kABPersonPrefixProperty,前缀

kABPersonSuffixProperty,后缀

kABPersonNicknameProperty,昵称

kABPersonFirstNamePhoneticProperty,名字汉语拼音或音标

kABPersonLastNamePhoneticProperty,姓氏汉语拼音或音标

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

kABPersonOrganizationProperty,组织名

kABPersonJobTitleProperty,头衔

kABPersonDepartmentProperty,部门

kABPersonNoteProperty,备注

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

[cpp]
CFTypeRef ABRecordCopyValue ( 
 
ABRecordRef record, 
 
ABPropertyID property 
 
); 

CFTypeRef ABRecordCopyValue (

ABRecordRef record,

ABPropertyID property

);


ABRecordRef参数是记录对象,ABPropertyID是属性ID,就是上面的常量kABPersonFirstNameProperty等。返回值类型是CFTypeRef,它是Core Foundation类型的“泛型”,可以代表任何的Core Foundation类型。

ViewController.m中的tableView:cellForRowAtIndexPath:方法,主要实现了访问单值属性:

[cpp]
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
 

 
static NSString *CellIdentifier = @”Cell”; 
 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
 
if (cell == nil) { 
 
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
 

 
ABRecordRef thisPerson = CFBridgingRetain([self.listContacts objectAtIndex:[indexPath row]]); ①        NSString *firstName = CFBridgingRelease(ABRecordCopyValue(thisPerson, kABPersonFirstNameProperty)); ② 
 
firstName = firstName != nil?firstName:@”"; 
 
NSString *lastName =  CFBridgingRelease(ABRecordCopyValue(thisPerson, kABPersonLastNameProperty));  ③ 
 
lastName = lastName != nil?lastName:@”"; 
 
cell.textLabel.text = [NSString stringWithFormat:@"%@ %@",firstName,lastName]; 
 
CFRelease(thisPerson); 
 
return cell; 
 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

static NSString *CellIdentifier = @”Cell”;

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {

cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

}

ABRecordRef thisPerson = CFBridgingRetain([self.listContacts objectAtIndex:[indexPath row]]); ①        NSString *firstName = CFBridgingRelease(ABRecordCopyValue(thisPerson, kABPersonFirstNameProperty)); ②

firstName = firstName != nil?firstName:@”";

NSString *lastName =  CFBridgingRelease(ABRecordCopyValue(thisPerson, kABPersonLastNameProperty));  ③

lastName = lastName != nil?lastName:@”";

cell.textLabel.text = [NSString stringWithFormat:@"%@ %@",firstName,lastName];

CFRelease(thisPerson);

return cell;

}


第①行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:方法完成的:

[cpp]
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
 

 
if ([[segue identifier] isEqualToString:@”showDetail”]) { 
 
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; 
 
ABRecordRef thisPerson = CFBridgingRetain([self.listContacts objectAtIndex:[indexPath row]]); 
 
DetailViewController *detailViewController = [segue destinationViewController]; 
 
ABRecordID personID = ABRecordGetRecordID(thisPerson); ① 
 
NSNumber *personIDAsNumber = [NSNumber numberWithInt:personID];  ② 
 
detailViewController.personIDAsNumber = personIDAsNumber;  ③ 
 
CFRelease(thisPerson);  ④ 
 

 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

{

if ([[segue identifier] isEqualToString:@”showDetail”]) {

NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];

ABRecordRef thisPerson = CFBridgingRetain([self.listContacts objectAtIndex:[indexPath row]]);

DetailViewController *detailViewController = [segue destinationViewController];

ABRecordID personID = ABRecordGetRecordID(thisPerson); ①

NSNumber *personIDAsNumber = [NSNumber numberWithInt:personID];  ②

detailViewController.personIDAsNumber = personIDAsNumber;  ③

CFRelease(thisPerson);  ④

}

}


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

#import <UIKit/UIKit.h>

#import <AddressBook/AddressBook.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是不能重复的

 

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

[cpp]
CFArrayRef ABMultiValueCopyArrayOfAllValues ( 
 
ABMultiValueRef multiValue 
 
); 
 
ABMultiValueCopyLabelAtIndex函数可以从ABMultiValueRef对象中返回标签,其定义如下: 
 
CFStringRef ABMultiValueCopyLabelAtIndex ( 
 
ABMultiValueRef multiValue, 
 
CFIndex index 
 
); 

CFArrayRef ABMultiValueCopyArrayOfAllValues (

ABMultiValueRef multiValue

);

ABMultiValueCopyLabelAtIndex函数可以从ABMultiValueRef对象中返回标签,其定义如下:

CFStringRef ABMultiValueCopyLabelAtIndex (

ABMultiValueRef multiValue,

CFIndex index

);


参数multiValue是ABMultiValueRef对象,index是查找标签的索引。

ABMultiValueGetIdentifierAtIndex函数可以从ABMultiValueRef对象中返回ID,其定义如下:

[cpp]
ABMultiValueIdentifier ABMultiValueGetIdentifierAtIndex ( 
 
ABMultiValueRef multiValue, 
 
CFIndex index 
 
); 
 
在DetailViewController.m文件viewDidLoad方法中取得Email多值属性,其代码如下: 
 
ABMultiValueRef emailsProperty = ABRecordCopyValue(person, kABPersonEmailProperty); 
 
NSArray* emailsArray = CFBridgingRelease(ABMultiValueCopyArrayOfAllValues(emailsProperty)); 
 
for(int index = 0; index< [emailsArray count]; index++){ 
 
NSString *email = [emailsArray objectAtIndex:index]; 
 
NSString *emailLabel = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(emailsProperty, index)); 
 
if ([emailLabel isEqualToString:(NSString*)kABWorkLabel]) { 
 
[self.lblWorkEmail setText:email]; 
 
} else if ([emailLabel isEqualToString:(NSString*)kABHomeLabel]) { 
 
[self.lblHomeEmail setText:email]; 
 
} else { 
 
NSLog(@”%@: %@”, @”其它Email”, email); 
 

 

 
CFRelease(emailsProperty); 

ABMultiValueIdentifier ABMultiValueGetIdentifierAtIndex (

ABMultiValueRef multiValue,

CFIndex index

);

在DetailViewController.m文件viewDidLoad方法中取得Email多值属性,其代码如下:

ABMultiValueRef emailsProperty = ABRecordCopyValue(person, kABPersonEmailProperty);

NSArray* emailsArray = CFBridgingRelease(ABMultiValueCopyArrayOfAllValues(emailsProperty));

for(int index = 0; index< [emailsArray count]; index++){

NSString *email = [emailsArray objectAtIndex:index];

NSString *emailLabel = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(emailsProperty, index));

if ([emailLabel isEqualToString:(NSString*)kABWorkLabel]) {

[self.lblWorkEmail setText:email];

} else if ([emailLabel isEqualToString:(NSString*)kABHomeLabel]) {

[self.lblHomeEmail setText:email];

} else {

NSLog(@”%@: %@”, @”其它Email”, email);

}

}

CFRelease(emailsProperty);


其中ABMultiValueCopyArrayOfAllValues(emailsProperty))语句是从emailsProperty属性中取出数组集合。kABWorkLabel和kABHomeLabel都是Email多值属性的标签。kABWorkLabel是工作Email标签和kABHomeLabel是家庭Email标签,另外还有kABOtherLabel,它是Email标签。最后emailsProperty需要释放。

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

[cpp]
ABMultiValueRef phoneNumberProperty = ABRecordCopyValue(person, kABPersonPhoneProperty); 
 
NSArray* phoneNumberArray = CFBridgingRelease(ABMultiValueCopyArrayOfAllValues(phoneNumberProperty)); 
 
for(int index = 0; index< [phoneNumberArray count]; index++){ 
 
NSString *phoneNumber = [phoneNumberArray objectAtIndex:index]; 
 
NSString *phoneNumberLabel = 
 
CFBridgingRelease(ABMultiValueCopyLabelAtIndex(phoneNumberProperty, index)); 
 
if ([phoneNumberLabel isEqualToString:(NSString*)kABPersonPhoneMobileLabel]) { 
 
[self.lblMobile setText:phoneNumber]; 
 
} else if ([phoneNumberLabel isEqualToString:(NSString*)kABPersonPhoneIPhoneLabel]) { 
 
[self.lblIPhone setText:phoneNumber]; 
 
} else { 
 
NSLog(@”%@: %@”, @”其它电话”, phoneNumber); 
 

 

 
CFRelease(phoneNumberProperty); 

ABMultiValueRef phoneNumberProperty = ABRecordCopyValue(person, kABPersonPhoneProperty);

NSArray* phoneNumberArray = CFBridgingRelease(ABMultiValueCopyArrayOfAllValues(phoneNumberProperty));

for(int index = 0; index< [phoneNumberArray count]; index++){

NSString *phoneNumber = [phoneNumberArray objectAtIndex:index];

NSString *phoneNumberLabel =

CFBridgingRelease(ABMultiValueCopyLabelAtIndex(phoneNumberProperty, index));

if ([phoneNumberLabel isEqualToString:(NSString*)kABPersonPhoneMobileLabel]) {

[self.lblMobile setText:phoneNumber];

} else if ([phoneNumberLabel isEqualToString:(NSString*)kABPersonPhoneIPhoneLabel]) {

[self.lblIPhone setText:phoneNumber];

} else {

NSLog(@”%@: %@”, @”其它电话”, phoneNumber);

}

}

CFRelease(phoneNumberProperty);


kABPersonPhoneMobileLabel和kABPersonPhoneIPhoneLabel都是电话号码属性的标签。kABPersonPhoneMobileLabel是移动电话号码标签,kABPersonPhoneIPhoneLabel是iPhone电话号码标签。此外还有:

kABPersonPhoneMainLabel,主要电话号码标签;

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

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

kABPersonPhonePagerLabel,寻呼机号码标签。

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

[cpp]
CFDataRef ABPersonCopyImageData ( 
 
ABRecordRef person 
 
); 

CFDataRef ABPersonCopyImageData (

ABRecordRef person

);


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

[cpp]
bool ABPersonHasImageData ( 
 
ABRecordRef person 
 
); 
 
DetailViewController.m中的viewDidLoad方法中取得联系人图片代码如下: 
 
if (ABPersonHasImageData(person)) { 
 
NSData *photoData = CFBridgingRelease(ABPersonCopyImageData(person)); 
 
if(photoData){ 
 
[self.imageView setImage:[UIImage imageWithData:photoData]]; 
 

 

bool ABPersonHasImageData (

ABRecordRef person

);

DetailViewController.m中的viewDidLoad方法中取得联系人图片代码如下:

if (ABPersonHasImageData(person)) {

NSData *photoData = CFBridgingRelease(ABPersonCopyImageData(person));

if(photoData){

[self.imageView setImage:[UIImage imageWithData:photoData]];

}

}


ABPersonCopyImageData取出的是CFDataRef类型,将其转化为NSData*,再使用UIImage的构造方法imageWithData:构建UIImage对象,然后再把UIImage对象赋值给imageView图片控件。


转自  http://www.2cto.com/kf/201307/224185.htmliOS

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值