四、关于ABMultiValueRef
如上所述,我们在获取联系人相关信息时,很多场景都会获取一组,例如对于电话号码,地址,邮箱这类的数据。在AddressBook框架中,这一组数据被封装为ABMultiValueRef对象。对于ABMultiValueRef对象,有如下方法可以对其进行处理:
//获取内部封装值的类型
/*
enum {
kABInvalidPropertyType = 0x0, // 无效
kABStringPropertyType = 0x1, // 字符串
kABIntegerPropertyType = 0x2, // 整数
kABRealPropertyType = 0x3, // 属性
kABDateTimePropertyType = 0x4, // 时间
kABDictionaryPropertyType = 0x5, // 字典
kABMultiStringPropertyType = kABMultiValueMask | kABStringPropertyType, // 聚合字符串
kABMultiIntegerPropertyType = kABMultiValueMask | kABIntegerPropertyType, // 聚合整型
kABMultiRealPropertyType = kABMultiValueMask | kABRealPropertyType, // 聚合属性
kABMultiDateTimePropertyType = kABMultiValueMask | kABDateTimePropertyType, // 聚合时间
kABMultiDictionaryPropertyType = kABMultiValueMask | kABDictionaryPropertyType, // 聚合字典
};
*/
ABPropertyType ABMultiValueGetPropertyType(ABMultiValueRef multiValue)
//获取其中封装的值的个数
CFIndex ABMultiValueGetCount(ABMultiValueRef multiValue)
//根据索引获取值
ABMultiValueCopyValueAtIndex(ABMultiValueRef multiValue, CFIndex index)
//获取所有的值 组成数组
CFArrayRef ABMultiValueCopyArrayOfAllValues(ABMultiValueRef multiValue)
//根据索引获取标签
CFStringRef ABMultiValueCopyLabelAtIndex(ABMultiValueRef multiValue, CFIndex index)
//根据ID获取值
ABMultiValueIdentifier ABMultiValueGetIdentifierAtIndex(ABMultiValueRef multiValue, CFIndex index)
//根据ID 获取索引
CFIndex ABMultiValueGetIndexForIdentifier(ABMultiValueRef multiValue, ABMultiValueIdentifier identifier)
//获取第一个值
CFIndex ABMultiValueGetFirstIndexOfValue(ABMultiValueRef multiValue, CFTypeRef value)
//下面这些与写联系人信息相关
//创建一个可变的数据对象
ABMutableMultiValueRef ABMultiValueCreateMutable(ABPropertyType type)
//为某个标签添加值
bool ABMultiValueAddValueAndLabel(ABMutableMultiValueRef multiValue, CFTypeRef value, CFStringRef label, ABMultiValueIdentifier *outIdentifier)
//在某个索引处插入 标签和值
bool ABMultiValueInsertValueAndLabelAtIndex(ABMutableMultiValueRef multiValue, CFTypeRef value, CFStringRef label, CFIndex index, ABMultiValueIdentifier *outIdentifier)
//删除某个索引处的标签和值
bool ABMultiValueRemoveValueAndLabelAtIndex(ABMutableMultiValueRef multiValue, CFIndex index)
//替换某个索引处的值
bool ABMultiValueReplaceValueAtIndex(ABMutableMultiValueRef multiValue, CFTypeRef value, CFIndex index)
//替换某个索引处的标签
bool ABMultiValueReplaceLabelAtIndex(ABMutableMultiValueRef multiValue, CFStringRef label, CFIndex index)
五、ABRecordRef对象
ABRecordRef虽然很多时候,我们可以把它理解为联系人对象,但是其实并不正确,实际上它是一个抽象的记录对象,在AddressBook框架中有3种类型的ABRecordRef:
enum {
kABPersonType = 0, //联系人类型
kABGroupType = 1, //组类型
kABSourceType = 2 //资源类型
};
可以操作ABRecordRef的方法非常简单,无非读与写,如下:
//获取记录类型
ABRecordType ABRecordGetRecordType(ABRecordRef record);
//获取记录中的数据
CFTypeRef ABRecordCopyValue(ABRecordRef record, ABPropertyID property);
//设置记录中的数据
bool ABRecordSetValue(ABRecordRef record, ABPropertyID property, CFTypeRef value, CFErrorRef* error);
//删除记录中的数据
bool ABRecordRemoveValue(ABRecordRef record, ABPropertyID property, CFErrorRef* error);
六、联系人组
在iOS系统的联系人应用中,我们可以对联系人进行分组,如下图所示:
AddressBook框架中的如下方法与联系人组操作相关:
//创建一个联系人组记录
ABRecordRef ABGroupCreate(void);
//在指定的资源中创建
ABRecordRef ABGroupCreateInSource(ABRecordRef source);
//获取资源
ABRecordRef ABGroupCopySource(ABRecordRef group);
//获取组中的所有成员
CFArrayRef ABGroupCopyArrayOfAllMembers(ABRecordRef group);
//根据指定的排序方法获取组中所有成员
CFArrayRef ABGroupCopyArrayOfAllMembersWithSortOrdering(ABRecordRef group, ABPersonSortOrdering sortOrdering);
//向组中添加成员
bool ABGroupAddMember(ABRecordRef group, ABRecordRef person, CFErrorRef* error);
//删除组中的成员
bool ABGroupRemoveMember(ABRecordRef group, ABRecordRef member, CFErrorRef* error);
//根据某条记录获取组
ABRecordRef ABAddressBookGetGroupWithRecordID(ABAddressBookRef addressBook, ABRecordID recordID);
//获取通讯录中所有组的个数
CFIndex ABAddressBookGetGroupCount(ABAddressBookRef addressBook);
//获取通讯录中所有组
CFArrayRef ABAddressBookCopyArrayOfAllGroups(ABAddressBookRef addressBook);
CFArrayRef ABAddressBookCopyArrayOfAllGroupsInSource(ABAddressBookRef addressBook, ABRecordRef source);
七、重中之重——ABAddressBookRef对象
前面介绍了许多操作联系人,操作组的方法,所有这些操作的基础都是基于一个通讯录对象ABAddressBookRef的。除了最前面演示的申请权限的相关方法,如下列举了与ABAddressBookRef相关的其他常用函数:
//存储通讯录
bool ABAddressBookSave(ABAddressBookRef addressBook, CFErrorRef* error);
//获取通讯录是否有未保存的更改
bool ABAddressBookHasUnsavedChanges(ABAddressBookRef addressBook);
//向通讯录中添加一条记录
bool ABAddressBookAddRecord(ABAddressBookRef addressBook, ABRecordRef record, CFErrorRef* error);
//移除通讯录中的一条记录
bool ABAddressBookRemoveRecord(ABAddressBookRef addressBook, ABRecordRef record, CFErrorRef* error);
//注册通讯录发生变化时的外部监听
void ABAddressBookRegisterExternalChangeCallback(ABAddressBookRef addressBook, ABExternalChangeCallback callback, void *context);
//移除通讯录发生变化时的外部监听
void ABAddressBookUnregisterExternalChangeCallback(ABAddressBookRef addressBook, ABExternalChangeCallback callback, void *context);
//将未保存的更改重置
void ABAddressBookRevert(ABAddressBookRef addressBook);
//工具方法,进行标签的本地化转换
CFStringRef ABAddressBookCopyLocalizedLabel(CFStringRef label);