关闭

iOS通讯录介绍

标签: ios通讯录
440人阅读 评论(0) 收藏 举报
分类:

自从 iOS6 以来,苹果严格限制了如何访问用户个人信息,比如通讯录信息。
当尝试访问用户个人信息时,会弹出一个对话框询问用户是否允许程序对个人数据进行访问,为了保证正常访问用户的通讯录,需要检查一下是否可以进行访问,也就是程序的授权状态。

查询授权状态:
可以调用ABAddressBookGetAuthorizationStatus函数进行查询授权状态,返回值有以下几种情况:
kABAuthorizationStatusNotDetermined = 0
用户还没有决定是否授权你的程序进行访问;
kABAuthorizationStatusRestricted = 1
iOS设备上的家长控制或其它一些许可配置阻止了你的程序与通讯录数据库进行交互;
kABAuthorizationStatusDenied = 2
用户明确的拒绝了你的程序对通讯录的访问;
kABAuthorizationStatusAuthorized = 3
用户已经授权给你的程序对通讯录进行访问。

//获得授权状态
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();

申请授权:
如果应用的授权状态是kABAuthorizationStatusNotDetermined,那么可以使用 ABAddressBookRequestAccessWithCompletion函数请求用户授权对通讯录的访问。
ABAddressBookRequestAccessWithCompletion函数的第1个参数是通讯录实例、第2个参数是一个block,无论授权结果如何,都会调用,并传入一个bool变量表示授权成功还是失败,一般都是在程序启动完毕后就申请授权(在AppDelegate的application:didFinishLaunchingWithOptions:方法中)。

获得所有的联系人数据:授权成功后,可以通过调用ABAddressBookCopyArrayOfAllPeople获得所有的联系人数据,这个函数返回一个CFArrayRef类型的数组。

// 获得所有的联系人
CFArrayRef array = ABAddressBookCopyArrayOfAllPeople(book);
// 联系人的总数
int count = CFArrayGetCount(array);
for (int i = 0; i < count; i++){
    // 获得某个联系人
      ABRecordRef person = CFArrayGetValueAtIndex(array, i);
}
// 释放
CFRelease(array);

通讯录数组中的每条记录都是一个ABRecordRef类型的数据,可以是一个群或一个人。
为了方便操作,也可以将CFArrayRef转成NSArray类型的数组:

NSArray *array = (__bridge  NSArray *) ABAddressBookCopyArrayOfAllPeople(book);
int count = array.count;
for (int i = 0; i < count; i++){
    ABRecordRef person = (__bridge ABRecordRef)array[i];
}

获得联系人的简单属性:
一个联系人就是一个ABRecordRef,每个联系人都有自己的属性,比如名字、电话、邮件等,使用ABRecordCopyValue函数可以从ABRecordRef中获得联系人的属性,ABRecordCopyValue函数接收2个参数,第1个参数ABRecordRef实例,第2个参数决定想要获得哪个属性。

// 获得名
CFStringRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);
// 获得姓
CFStringRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);
kABPersonFirstNameProperty和kABPersonLastNameProperty属性返回的都是CFStringRef类型的数据,由于是Copy出来的,最后需要CFRelease一下

为了方便操作,也可以将CFStringRef转为 NSString进行操作:

// 获得名
NSString *firstName = (__bridge NSString *) ABRecordCopyValue(person, kABPersonFirstNameProperty);

// 获得姓
NSString *lastName = (__bridge NSString *) ABRecordCopyValue(person, kABPersonLastNameProperty);

获得联系人的复杂属性:
前面获得了联系人的姓、名属性值,都是非常简单的,一个属性对应一个字符串值,联系人的有些属性值就没这么简单,一个属性可能会包含多个值,比如邮箱,分为工作邮箱、住宅邮箱、其他邮箱等。
如果是复杂属性,那么ABRecordCopyValue函数返回的就是ABMultiValueRef类型的数据。

获得所有的邮箱地址:

int count = ABMultiValueGetCount(emails);
for (int i = 0; i < count; i++){
    // 获得标签名
        CFStringRef emailLabel = ABMultiValueCopyLabelAtIndex(emails, i);
    // 转为本地标签名(能看得懂的标签名,比如work、home)
     CFStringRef localizedEmailLabel = ABAddressBookCopyLocalizedLabel(emailLabel);

    // 获得邮件地址值
        CFStringRef email = ABMultiValueCopyValueAtIndex(emails, i);

    NSLog(@"%@-%@:%@", emailLabel, localizedEmailLabel, email);

    // 释放
    CFRelease(emailLabel);
    CFRelease(localizedEmailLabel);
    CFRelease(email);
}

如果不想管理内存,可以将CFStringRef转为NSString:

// 获得标签名
NSString *emailLabel = (__bridge NSString *)(ABMultiValueCopyLabelAtIndex(emails, i));
// 转为本地标签名(能看得懂的标签名,比如work、home)
NSString *localizedEmailLabel = (__bridge NSString *)(ABAddressBookCopyLocalizedLabel((__bridge CFStringRef)(emailLabel)));

// 获得邮件地址值
NSString *email = (__bridge NSString *)(ABMultiValueCopyValueAtIndex(emails, i));

NSLog(@"%@-%@:%@", emailLabel, localizedEmailLabel, email);

添加联系人的步骤:
通过ABPersonCreate函数创建一个新的联系人(返回ABRecordRef);
通过ABRecordSetValue函数设置联系人的属性;
通过ABAddressBookAddRecord函数将联系人添加到通讯录数据库中;
通过ABAddressBookSave函数保存刚才所作的修改;
可以通过ABAddressBookHasUnsavedChanges函数判断是否有未保存的修改;
当决定是否更改通讯录数据库后,你可以分别使用AbAddressBookSave 或 ABAddressBookRevert 方式来保存或放弃更改。

添加联系人代码实现:

// 创建联系人
ABRecordRef person = ABPersonCreate();

// 设置属性
ABRecordSetValue(person, kABPersonFirstNameProperty, @"名字", NULL);
ABRecordSetValue(person, kABPersonLastNameProperty, @"姓氏", NULL);

// 通讯录实例
ABAddressBookRef book = ABAddressBookCreateWithOptions(NULL, NULL);
// 添加联系人
ABAddressBookAddRecord(book, person, NULL);

// 保存修改
ABAddressBookSave(book, NULL);

// 释放
CFRelease(person);
CFRelease(book);

添加一些复杂的属性:

// 设置邮箱属性的内容
ABMultiValueRef email = ABMultiValueCreateMutable(kABStringPropertyType);
// 工作邮箱
ABMultiValueAddValueAndLabel(email, @"work@qq.com", kABWorkLabel, NULL);
// 家庭邮箱
ABMultiValueAddValueAndLabel(email, @"home@qq.com", kABHomeLabel, NULL);
// 添加邮箱属性
ABRecordSetValue(person, kABPersonEmailProperty, email, NULL);
CFRelease(email);

添加群组的步骤:
通过ABPersonCreate函数创建一个新的组(返回ABRecordRef);
通过ABRecordSetValue函数设置组名;
通过ABAddressBookAddRecord函数将组添加到通讯录数据库中;
通过ABAddressBookSave函数保存刚才所作的修改。
其代码实现:

// 创建组
ABRecordRef group = ABGroupCreate();
// 设置组名
ABRecordSetValue(group, kABGroupNameProperty, @"家人", NULL);
// 通讯录实例
ABAddressBookRef book = ABAddressBookCreateWithOptions(NULL, NULL);
// 添加组
ABAddressBookAddRecord(book, group, NULL);
// 保存修改
ABAddressBookSave(book, NULL);

CFRelease(book);
CFRelease(group);

另外,如果想获取所有的群组信息,可以使用ABAddressBookCopyArrayOfAllGroups函数;
如果想添加联系人到组中,可以使用ABGroupAddMember函数;
如果想从组中移除联系人,可以使用ABGroupRemoveMember函数;
如果想从通讯录中移除组或者联系人,可以使用ABAddressBookRemoveRecord函数。

想操作联系人的头像,有以下函数:
BPersonHasImageData:判断通讯录中的联系人是否有图片;
ABPersonCopyImageData:取得图片数据(假如有的话);
ABPersonSetImageData:设置联系人的图片数据。

设置图片数据:

NSData *data = UIImageJPEGRepresentation([UIImage imageNamed:@"name.jpg"], 1);
ABPersonSetImageData(person, (__bridge CFDataRef)(data), NULL);

获得图片数据:

if(ABPersonHasImageData(person)) {
    NSData *data = (__bridge NSData *)ABPersonCopyImageData(person);
    _imageView.image = [UIImage imageWithData:data];
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:19328次
    • 积分:672
    • 等级:
    • 排名:千里之外
    • 原创:49篇
    • 转载:3篇
    • 译文:0篇
    • 评论:0条
    文章分类