四、關于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:
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);