原文地址:http://blog.csdn.net/zeng_zhiming/article/details/70141316
在ios開發中, 通訊錄操作還是比較常見的, 尤其是在社交項目中更爲突出. 目前系統提供了兩個框架對通訊錄進行操作:
1. 兼容iOS9以前的框架
#import <AddressBook/AddressBook.h>
2.iOS9以後的新框架
#import <ContactsUI/ContactsUI.h>
爲了項目能兼容老版本, 本文主要整理<AddressBook>的使用:
一. 判斷通訊錄權限
// 判斷權限
switch (ABAddressBookGetAuthorizationStatus()) {
case kABAuthorizationStatusNotDetermined: //!< 未選擇權限.
{
}
break;
case kABAuthorizationStatusRestricted: //!< 權限被限制.
{
}
break;
case kABAuthorizationStatusDenied: //!< 已拒絕權限.
{
}
break;
case kABAuthorizationStatusAuthorized: //!< 已授權.
{
}
break;
default:
break;
}
二. 請求通訊錄訪問權限
/**
請求通訊錄訪問權限
@param completion 權限回調
*/
- (void)requestAddressBookAccessWithCompletion:(void (^)(int code, NSString *msg))completion
{
// 請求訪問用戶通訊錄,注意無論成功與否block都會調用
ABAddressBookRequestAccessWithCompletion(_addressBook, ^(bool granted, CFErrorRef error) {
// 回調到主線程返回結果
dispatch_async(dispatch_get_main_queue(), ^{
if (granted) {
if (completion) completion(1, @"請求通訊錄訪問權限成功");
} else {
if (completion) completion(-1, @"請求通訊錄訪問權限失敗");
}
});
});
}
三. 通訊錄操作
1. 獲取通訊錄聯繫人列表
/**
* 同步獲取通訊錄聯繫人列表
*
* @return 通訊錄ZMPersonModel數組
*/
- (NSArray<ZMPersonModel *> *)getAddressBookPersonListWithSort:(PersonSort)personSort
{
// 檢測權限
if (ABAddressBookGetAuthorizationStatus() != kABAuthorizationStatusAuthorized) {
return nil;
}
// 按照排序讀取所有聯繫人
CFArrayRef allPerson = NULL;
switch (personSort) {
case SortByFirstName: //!< 名字排序.
allPerson = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(_addressBook, kABSourceTypeLocal, kABPersonSortByFirstName);
break;
case SortByLastName: //!< 姓氏排序.
allPerson = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(_addressBook, kABSourceTypeLocal, kABPersonSortByLastName);
break;
case SortByCreationTime://!< 創建時間排序.
default:
allPerson = ABAddressBookCopyArrayOfAllPeople(_addressBook);
break;
}
// 存儲通訊錄的數組
NSMutableArray<ZMPersonModel *> *addressBookArray = [NSMutableArray array];
// 循環遍歷,獲取每個聯繫人信息
for (NSInteger i = 0; i < CFArrayGetCount(allPerson); i++) {
ABRecordRef person = CFArrayGetValueAtIndex(allPerson, i);
ZMPersonModel *personModel = [[ZMPersonModel alloc] initWithPerson:person];
[addressBookArray addObject:personModel];
}
// 釋放資源
if (allPerson) CFRelease(allPerson);
return addressBookArray;
}
2. 根據RecordID查找聯繫人
/**
根據RecordID查找聯繫人
@param recordID 聯繫人ID
@return ZMPersonModel對象
*/
- (ZMPersonModel *)getPersonWithRecordID:(ABRecordID)recordID
{
// 獲取Person
ABRecordRef person = ABAddressBookGetPersonWithRecordID(_addressBook, recordID);
// 初始化爲ZMPersonModel
ZMPersonModel *personModel = [[ZMPersonModel alloc] initWithPerson:person];
return personModel;
}
3. 根據Name查找聯繫人
/**
根據Name查找聯繫人
@param name 查找關鍵字
@return ZMPersonModel數組
*/
- (NSArray<ZMPersonModel *> *)getPersonsWithName:(NSString *)name
{
// 空值過濾
if (name == nil || name.length == 0) {
return nil;
}
// 根據Name獲取聯繫人
CFArrayRef persons = ABAddressBookCopyPeopleWithName(_addressBook, (__bridge CFStringRef)(name));
// 存儲通訊錄的數組
NSMutableArray<ZMPersonModel *> *personArray = [NSMutableArray array];
// 循環遍歷,獲取每個聯繫人信息
for (NSInteger i = 0; i < CFArrayGetCount(persons); i++) {
ABRecordRef person = CFArrayGetValueAtIndex(persons, i);
ZMPersonModel *personModel = [[ZMPersonModel alloc] initWithPerson:person];
[personArray addObject:personModel];
}
// 釋放資源
if (persons) CFRelease(persons);
return personArray;
}
4. 添加聯繫到通訊錄
/**
批量添加聯繫到通訊錄
@param personArray ZMPersonModel數組
@return 添加結果
*/
- (BOOL)addPersons:(NSArray<ZMPersonModel *> *)personArray
{
// 空值過濾
if (personArray == nil || personArray.count == 0) {
return NO;
}
// 添加結果
BOOL result = YES;
// 遍歷數組將聯繫人添加到通訊錄中
for (ZMPersonModel *personModel in personArray)
{
// 實例化CFErrorRef
CFErrorRef errorRef = NULL;
// 添加聯繫人
if (ABAddressBookAddRecord(_addressBook, [personModel getRecordRef], &errorRef) == true) {
// 保存通訊錄
if (!ABAddressBookSave(_addressBook, &errorRef)) {
result = NO;
}
}
// 錯誤消息處理
if (errorRef) {
NSLog(@"Add Person Error:%@", errorRef);
CFRelease(errorRef);
}
}
return result;
}
5. 修改聯繫人
/**
更新聯繫人
@param personModel ZMPersonModel對象
@return 更新結果
*/
- (BOOL)updatePerson:(ZMPersonModel *)personModel
{
BOOL result = NO;
// 空值過濾
if (personModel == nil) {
return result;
}
// 實例化CFErrorRef
CFErrorRef errorRef = NULL;
// 獲取Person
ABRecordRef person = ABAddressBookGetPersonWithRecordID(_addressBook, personModel.recordID);
// 將Model中數據更新到person中
if ([personModel updateToRecordRef:person]) {
// 保存通訊錄
result = ABAddressBookSave(_addressBook, &errorRef);
}
// 錯誤消息處理
if (errorRef) {
NSLog(@"Add Person Error:%@", errorRef);
CFRelease(errorRef);
}
return result;
}
6. 刪除聯繫人
/**
根據RecordID刪除聯繫人
@param recordID 聯繫人ID
@return 刪除結果
*/
- (BOOL)removePersonWithRecordID:(ABRecordID)recordID
{
BOOL result = NO;
// 實例化CFErrorRef
CFErrorRef errorRef = NULL;
// 獲取Person
ABRecordRef person = ABAddressBookGetPersonWithRecordID(_addressBook, recordID);
if ((person != NULL) && ABAddressBookRemoveRecord(_addressBook, person, &errorRef)) {
// 保存通訊錄
if (ABAddressBookSave(_addressBook, &errorRef)) {
result = YES;
}
}
// 錯誤消息處理
if (errorRef) {
NSLog(@"Remove Person Error:%@", errorRef);
CFRelease(errorRef);
}
return result;
}
四. 聯繫人數據解析
1. 解析聯繫人所以數據
/**
設置屬性值
*/
- (void)setValueWithPerson:(ABRecordRef)person
{
// 空值過濾
if (person == NULL) {
return;
}
/** 獲取RecordID */
_recordID = ABRecordGetRecordID(person);
/** 姓名相關 */
_firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty)); //!< 名字.
_lastName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty)); //!< 姓氏.
_middleName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonMiddleNameProperty));//!< 中間名.
_prefix = CFBridgingRelease(ABRecordCopyValue(person, kABPersonPrefixProperty)); //!< 前綴.
_suffix = CFBridgingRelease(ABRecordCopyValue(person, kABPersonSuffixProperty)); //!< 後綴.
_nickname = CFBridgingRelease(ABRecordCopyValue(person, kABPersonNicknameProperty)); //!< 暱稱.
_firstNamePhonetic = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNamePhoneticProperty)); //!< 名字拼音或音標.
_lastNamePhonetic = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNamePhoneticProperty)); //!< 姓氏拼音或音標.
_middleNamePhonetic = CFBridgingRelease(ABRecordCopyValue(person, kABPersonMiddleNamePhoneticProperty));//!< 中間名拼音或音標.
/** 工作相關 */
_organization = CFBridgingRelease(ABRecordCopyValue(person, kABPersonOrganizationProperty)); //!< 公司名稱.
_department = CFBridgingRelease(ABRecordCopyValue(person, kABPersonDepartmentProperty)); //!< 部門.
_jobTitle = CFBridgingRelease(ABRecordCopyValue(person, kABPersonJobTitleProperty)); //!< 職位.
/** 備註 */
_note = CFBridgingRelease(ABRecordCopyValue(person, kABPersonNoteProperty)); //!< 備註.
/** 日期相關 */
_birthday = CFBridgingRelease(ABRecordCopyValue(person, kABPersonBirthdayProperty)); //!< 生日.
_creationDate = CFBridgingRelease(ABRecordCopyValue(person, kABPersonCreationDateProperty)); //!< 創建時間.
_modificationDate = CFBridgingRelease(ABRecordCopyValue(person, kABPersonModificationDateProperty)); //!< 最近修改時間.
/** 農曆生日 */
NSDictionary *brithdayDict = CFBridgingRelease(ABRecordCopyValue(person, kABPersonAlternateBirthdayProperty));
if (!IsNullDictionary(brithdayDict))
{
ZMAlternateBirthdayModel *brithdayModel = [[ZMAlternateBirthdayModel alloc] init];
// 標誌
brithdayModel.calendar = [brithdayDict valueForKey:(NSString *)kABPersonAlternateBirthdayCalendarIdentifierKey];
// 紀元
brithdayModel.era = [[brithdayDict valueForKey:(NSString *)kABPersonAlternateBirthdayEraKey] integerValue];
// 年份
brithdayModel.year = [[brithdayDict valueForKey:(NSString *)kABPersonAlternateBirthdayYearKey] integerValue];
// 月份
brithdayModel.month = [[brithdayDict valueForKey:(NSString *)kABPersonAlternateBirthdayMonthKey] integerValue];
// 日期
brithdayModel.day = [[brithdayDict valueForKey:(NSString *)kABPersonAlternateBirthdayDayKey] integerValue];
// 是否閏月
brithdayModel.leapMonth = [[brithdayDict valueForKey:(NSString *)kABPersonAlternateBirthdayIsLeapMonthKey] boolValue];
_alternateBirthday = brithdayModel;
}
/** 分類 */
CFNumberRef kindType = ABRecordCopyValue(person, kABPersonKindProperty);
_kind = (kindType == kABPersonKindOrganization) ? KindOrganization : KindPerson;
if (kindType != NULL) CFRelease(kindType);
/** 頭像 */
if (ABPersonHasImageData(person) == true) {
// 獲得頭像原圖
NSData *imageData = CFBridgingRelease(ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatOriginalSize));
_headImage = [UIImage imageWithData:imageData];
}
/** 電子郵件列表 */
NSMutableArray<ZMLabelStringModel *> *emailArray = [NSMutableArray array];
ABMultiValueRef emailRef = ABRecordCopyValue(person, kABPersonEmailProperty);
for (int i = 0; i < ABMultiValueGetCount(emailRef); i++)
{
ZMLabelStringModel *emailModel = [[ZMLabelStringModel alloc] init];
// 標籤
emailModel.label = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(emailRef, i));;
// 郵箱地址
emailModel.content = CFBridgingRelease(ABMultiValueCopyValueAtIndex(emailRef, i));
// 添加到數組
[emailArray addObject:emailModel];
}
if (emailRef) CFRelease(emailRef);
_emails = emailArray;
/** 地址列表 */
NSMutableArray<ZMAddressModel *> *addressArray = [NSMutableArray array];
ABMultiValueRef addressRef = ABRecordCopyValue(person, kABPersonAddressProperty);
for(int i = 0; i < ABMultiValueGetCount(addressRef); i++)
{
ZMAddressModel *addressModel = [[ZMAddressModel alloc] init];
// 標籤
addressModel.label = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(addressRef, i));
// 獲取地址字典
NSDictionary *addressDict = CFBridgingRelease(ABMultiValueCopyValueAtIndex(addressRef, i));
if (!IsNullDictionary(addressDict)) {
// 街道
addressModel.street = [addressDict valueForKey:(NSString *)kABPersonAddressStreetKey];
// 城市
addressModel.city = [addressDict valueForKey:(NSString *)kABPersonAddressCityKey];
// 省
addressModel.state = [addressDict valueForKey:(NSString *)kABPersonAddressStateKey];
// 郵政編碼
addressModel.zip = [addressDict valueForKey:(NSString *)kABPersonAddressZIPKey];
// 國家
addressModel.country = [addressDict valueForKey:(NSString *)kABPersonAddressCountryKey];
// 國別碼
addressModel.countryCode = [addressDict valueForKey:(NSString *)kABPersonAddressCountryCodeKey];
}
// 添加到數組
[addressArray addObject:addressModel];
}
if (addressRef) CFRelease(addressRef);
_addresses = addressArray;
/** 日期列表 */
NSMutableArray <ZMLabelDateModel *> *dateArray = [NSMutableArray array];
ABMultiValueRef dateRef = ABRecordCopyValue(person, kABPersonDateProperty);
for (int i = 0; i < ABMultiValueGetCount(dateRef); i++)
{
ZMLabelDateModel *dateModel = [[ZMLabelDateModel alloc] init];
// 標籤
dateModel.label = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(dateRef, i));
// 日期
dateModel.date = CFBridgingRelease(ABMultiValueCopyValueAtIndex(dateRef, i));
// 添加到數組
[dateArray addObject:dateModel];
}
if (dateRef) CFRelease(dateRef);
_dates = dateArray;
/** 電話列表 */
NSMutableArray<ZMLabelStringModel *> *phoneArray = [NSMutableArray array];
ABMultiValueRef phoneRef = ABRecordCopyValue(person, kABPersonPhoneProperty);
for (int i = 0; i < ABMultiValueGetCount(phoneRef); i++)
{
ZMLabelStringModel *phoneModel = [[ZMLabelStringModel alloc] init];
// 標籤
phoneModel.label = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(phoneRef, i));
// 電話號碼
phoneModel.content = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phoneRef, i));
// 添加到數組
[phoneArray addObject:phoneModel];
}
if (phoneRef) CFRelease(phoneRef);
_phones = phoneArray;
/** 即時信息列表 */
NSMutableArray<ZMInstantMessageModel *> *instantMessageArray = [NSMutableArray array];
ABMultiValueRef instantMessageRef = ABRecordCopyValue(person, kABPersonInstantMessageProperty);
for (int i = 1; i < ABMultiValueGetCount(instantMessageRef); i++)
{
ZMInstantMessageModel *instantMessageModel = [[ZMInstantMessageModel alloc] init];
// 標籤
instantMessageModel.label = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(instantMessageRef, i));
// 獲取即時信息字典
NSDictionary *instantMessageDict = CFBridgingRelease(ABMultiValueCopyValueAtIndex(instantMessageRef, i));
if (!IsNullDictionary(instantMessageDict)) {
// 服務賬號
instantMessageModel.username = [instantMessageDict valueForKey:(NSString *)kABPersonInstantMessageUsernameKey];
// 服務名稱
instantMessageModel.service = [instantMessageDict valueForKey:(NSString *)kABPersonInstantMessageServiceKey];
}
// 添加到數組
[instantMessageArray addObject:instantMessageModel];
}
if (instantMessageRef) CFRelease(instantMessageRef);
_instantMessages = instantMessageArray;
/** URL列表 */
NSMutableArray<ZMLabelStringModel *> *urlArray = [NSMutableArray array];
ABMultiValueRef urlRef = ABRecordCopyValue(person, kABPersonURLProperty);
for (int i = 0; i < ABMultiValueGetCount(urlRef); i++)
{
ZMLabelStringModel *urlModel = [[ZMLabelStringModel alloc] init];
// 標籤
urlModel.label = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(urlRef,i));
// URL地址
urlModel.content = CFBridgingRelease(ABMultiValueCopyValueAtIndex(urlRef,i));
// 添加到數組
[urlArray addObject:urlModel];
}
if (urlRef) CFRelease(urlRef);
_urls = urlArray;
/** 關聯人列表 */
NSMutableArray<ZMLabelStringModel *> *relatedNameArray = [NSMutableArray array];
ABMultiValueRef relatedNameRef = ABRecordCopyValue(person, kABPersonRelatedNamesProperty);
for (int i = 0; i < ABMultiValueGetCount(relatedNameRef); i++)
{
ZMLabelStringModel *relatedNameModel = [[ZMLabelStringModel alloc] init];
// 標籤
relatedNameModel.label = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(relatedNameRef, i));
// 關聯人姓名
relatedNameModel.content = CFBridgingRelease(ABMultiValueCopyValueAtIndex(relatedNameRef, i));
// 添加到數組
[relatedNameArray addObject:relatedNameModel];
}
if (relatedNameRef) CFRelease(relatedNameRef);
_relatedNames = relatedNameArray;
/** 社交資料列表 */
NSMutableArray<ZMSocialProfileModel *> *socialProfileArray = [NSMutableArray array];
ABMultiValueRef socialProfileRef = ABRecordCopyValue(person, kABPersonSocialProfileProperty);
for (int i = 0 ; i < ABMultiValueGetCount(socialProfileRef); i++)
{
// 獲取社交資料字典
NSDictionary *socialProfileDict = CFBridgingRelease(ABMultiValueCopyValueAtIndex(socialProfileRef, i));
if (!IsNullDictionary(socialProfileDict)) {
ZMSocialProfileModel *socialProfileModel = [[ZMSocialProfileModel alloc] init];
// 社交鏈接
socialProfileModel.url = [socialProfileDict valueForKey:(NSString *)kABPersonSocialProfileURLKey];
// 服務名稱
socialProfileModel.service = [socialProfileDict valueForKey:(NSString *)kABPersonSocialProfileServiceKey];
// 社交服務賬號
socialProfileModel.username = [socialProfileDict valueForKey:(NSString *)kABPersonSocialProfileUsernameKey];
// 用戶標識
socialProfileModel.userIdentifier = [socialProfileDict valueForKey:(NSString *)kABPersonSocialProfileUserIdentifierKey];
// 添加到數組
[socialProfileArray addObject:socialProfileModel];
}
}
if (socialProfileRef) CFRelease(socialProfileRef);
_socialProfiles = socialProfileArray;
}
2. 生成聯繫所有數據
/**
將Model數據賦值到ABRecordRef
@param person ABRecordRef對象
@return 賦值結果
*/
- (BOOL)updateToRecordRef:(ABRecordRef)person
{
// 空值處理
if (person == NULL) {
return NO;
}
// 實例化CFErrorRef
CFErrorRef errorRef = NULL;
/** 姓名相關 */
ABRecordSetValue(person, kABPersonFirstNameProperty, (__bridge CFStringRef)(_firstName), &errorRef); //!< 名字.
ABRecordSetValue(person, kABPersonLastNameProperty, (__bridge CFStringRef)(_lastName), &errorRef); //!< 姓氏.
ABRecordSetValue(person, kABPersonMiddleNameProperty, (__bridge CFStringRef)(_middleName), &errorRef);//!< 中間名.
ABRecordSetValue(person, kABPersonPrefixProperty, (__bridge CFStringRef)(_prefix), &errorRef); //!< 前綴.
ABRecordSetValue(person, kABPersonSuffixProperty, (__bridge CFStringRef)(_suffix), &errorRef); //!< 後綴.
ABRecordSetValue(person, kABPersonNicknameProperty, (__bridge CFStringRef)(_nickname), &errorRef); //!< 暱稱.
ABRecordSetValue(person, kABPersonFirstNamePhoneticProperty, (__bridge CFStringRef)(_firstNamePhonetic), &errorRef); //!< 名字拼音或音標.
ABRecordSetValue(person, kABPersonLastNamePhoneticProperty, (__bridge CFStringRef)(_lastNamePhonetic), &errorRef); //!< 姓氏拼音或音標.
ABRecordSetValue(person, kABPersonMiddleNamePhoneticProperty, (__bridge CFStringRef)(_middleNamePhonetic), &errorRef);//!< 中間名拼音或音標.
/** 工作相關 */
ABRecordSetValue(person, kABPersonOrganizationProperty, (__bridge CFStringRef)(_organization), &errorRef);//!< 公司名稱.
ABRecordSetValue(person, kABPersonDepartmentProperty, (__bridge CFStringRef)(_department), &errorRef); //!< 部門.
ABRecordSetValue(person, kABPersonJobTitleProperty, (__bridge CFStringRef)(_jobTitle), &errorRef); //!< 職位.
/** 備註 */
ABRecordSetValue(person, kABPersonNoteProperty, (__bridge CFStringRef)(_note), &errorRef); //!< 備註.
/** 日期相關 */
ABRecordSetValue(person, kABPersonBirthdayProperty, (__bridge CFDateRef)(_birthday), &errorRef); //!< 生日.
ABRecordSetValue(person, kABPersonCreationDateProperty, (__bridge CFDateRef)(_creationDate), &errorRef); //!< 創建時間.
ABRecordSetValue(person, kABPersonModificationDateProperty, (__bridge CFDateRef)(_modificationDate), &errorRef);//!< 最近修改時間.
/** 農曆生日 */
if (_alternateBirthday)
{
NSMutableDictionary *brithdayDict = [NSMutableDictionary dictionary];
// 標誌
brithdayDict[(NSString *)kABPersonAlternateBirthdayCalendarIdentifierKey] = _alternateBirthday.calendar;
// 紀元
brithdayDict[(NSString *)kABPersonAlternateBirthdayEraKey] = @(_alternateBirthday.era);
// 年份
brithdayDict[(NSString *)kABPersonAlternateBirthdayYearKey] = @(_alternateBirthday.year);
// 月份
brithdayDict[(NSString *)kABPersonAlternateBirthdayMonthKey] = @(_alternateBirthday.month);
// 日期
brithdayDict[(NSString *)kABPersonAlternateBirthdayDayKey] = @(_alternateBirthday.day);
// 是否閏月
brithdayDict[(NSString *)kABPersonAlternateBirthdayIsLeapMonthKey] = @(_alternateBirthday.leapMonth);
ABRecordSetValue(person, kABPersonAlternateBirthdayProperty, (__bridge CFDictionaryRef)(brithdayDict), &errorRef);
}
/** 分類 */
CFNumberRef personKind = (_kind == KindOrganization) ? kABPersonKindOrganization : kABPersonKindPerson;
ABRecordSetValue(person, kABPersonKindProperty, personKind, &errorRef);
/** 頭像 */
if (_headImage) {
NSData *imageData = UIImagePNGRepresentation(_headImage);
ABPersonSetImageData(person, (__bridge CFDataRef)(imageData),&errorRef);
}
/** 電子郵件列表 */
ABMultiValueRef emailRef = ABMultiValueCreateMutable(kABMultiStringPropertyType);
for (ZMLabelStringModel *emailModel in _emails) {
ABMultiValueAddValueAndLabel(emailRef, (__bridge CFStringRef)(emailModel.content), (__bridge CFStringRef)(emailModel.label), NULL);
}
ABRecordSetValue(person, kABPersonEmailProperty, emailRef, &errorRef);
if (emailRef) CFRelease(emailRef);
/** 地址列表 */
ABMultiValueRef addressRef = ABMultiValueCreateMutable(kABMultiDictionaryPropertyType);
for (ZMAddressModel *addressModel in _addresses)
{
NSMutableDictionary *addressDict = [NSMutableDictionary dictionary];
// 街道
addressDict[(NSString *)kABPersonAddressStreetKey] = addressModel.street;
// 城市
addressDict[(NSString *)kABPersonAddressCityKey] = addressModel.city;
// 省
addressDict[(NSString *)kABPersonAddressStateKey] = addressModel.state;
// 郵政編碼
addressDict[(NSString *)kABPersonAddressZIPKey] = addressModel.zip;
// 國家
addressDict[(NSString *)kABPersonAddressCountryKey] = addressModel.country;
// 國別碼
addressDict[(NSString *)kABPersonAddressCountryCodeKey] = addressModel.countryCode;
ABMultiValueAddValueAndLabel(addressRef, (__bridge CFDictionaryRef)(addressDict), (__bridge CFStringRef)addressModel.label, NULL);
}
ABRecordSetValue(person, kABPersonAddressProperty, addressRef, &errorRef);
if (addressRef) CFRelease(addressRef);
/** 日期列表 */
ABMultiValueRef dateRef = ABMultiValueCreateMutable(kABMultiDateTimePropertyType);
for (ZMLabelDateModel *dateModel in _dates) {
ABMultiValueAddValueAndLabel(dateRef, (__bridge CFDateRef)(dateModel.date), (__bridge CFStringRef)(dateModel.label), NULL);
}
ABRecordSetValue(person, kABPersonDateProperty, dateRef, &errorRef);
if (dateRef) CFRelease(dateRef);
/** 電話列表 */
ABMultiValueRef phoneRef = ABMultiValueCreateMutable(kABMultiStringPropertyType);
for (ZMLabelStringModel *phoneModel in _phones) {
ABMultiValueAddValueAndLabel(phoneRef, (__bridge CFStringRef)(phoneModel.content), (__bridge CFStringRef)(phoneModel.label), NULL);
}
ABRecordSetValue(person, kABPersonPhoneProperty, phoneRef, &errorRef);
if (phoneRef) CFRelease(phoneRef);
/** 即時信息列表 */
ABMultiValueRef instantMessageRef = ABMultiValueCreateMutable(kABMultiDictionaryPropertyType);
for (ZMInstantMessageModel *instantMessageModel in _instantMessages)
{
NSMutableDictionary *instantMessageDict = [NSMutableDictionary dictionary];
// 服務賬號
instantMessageDict[(NSString *)kABPersonInstantMessageUsernameKey] = instantMessageModel.username;
// 服務名稱
instantMessageDict[(NSString *)kABPersonInstantMessageServiceKey] = instantMessageModel.service;
ABMultiValueAddValueAndLabel(instantMessageRef, (__bridge CFDictionaryRef)(instantMessageDict), (__bridge CFStringRef)instantMessageModel.label, NULL);
}
ABRecordSetValue(person, kABPersonInstantMessageProperty, instantMessageRef, &errorRef);
if (instantMessageRef) CFRelease(instantMessageRef);
/** URL列表 */
ABMultiValueRef urlRef = ABMultiValueCreateMutable(kABMultiStringPropertyType);
for (ZMLabelStringModel *urlModel in _urls) {
ABMultiValueAddValueAndLabel(urlRef, (__bridge CFStringRef)(urlModel.content), (__bridge CFStringRef)(urlModel.label), NULL);
}
ABRecordSetValue(person, kABPersonURLProperty, urlRef, &errorRef);
if (urlRef) CFRelease(urlRef);
/** 關聯人列表 */
ABMultiValueRef relatedNameRef = ABMultiValueCreateMutable(kABMultiStringPropertyType);
for (ZMLabelStringModel *relatedNameModel in _relatedNames) {
ABMultiValueAddValueAndLabel(relatedNameRef, (__bridge CFStringRef)(relatedNameModel.content), (__bridge CFStringRef)(relatedNameModel.label), NULL);
}
ABRecordSetValue(person, kABPersonRelatedNamesProperty, relatedNameRef, &errorRef);
if (relatedNameRef) CFRelease(relatedNameRef);
/** 社交資料列表 */
ABMultiValueRef socialProfileRef = ABMultiValueCreateMutable(kABMultiDictionaryPropertyType);
for (ZMSocialProfileModel *socialProfileModel in _socialProfiles)
{
NSMutableDictionary *socialProfileDict = [NSMutableDictionary dictionary];
// 社交鏈接
socialProfileDict[(NSString *)kABPersonSocialProfileURLKey] = socialProfileModel.url;
// 服務名稱
socialProfileDict[(NSString *)kABPersonSocialProfileServiceKey] = socialProfileModel.service;
// 社交服務賬號
socialProfileDict[(NSString *)kABPersonSocialProfileUsernameKey] = socialProfileModel.username;
// 用戶標識
socialProfileDict[(NSString *)kABPersonSocialProfileUserIdentifierKey] = socialProfileModel.userIdentifier;
ABMultiValueAddValueAndLabel(socialProfileRef, (__bridge CFDictionaryRef)(socialProfileDict), NULL, NULL);
}
ABRecordSetValue(person, kABPersonSocialProfileProperty, socialProfileRef, &errorRef);
if (socialProfileRef) CFRelease(socialProfileRef);
// 錯誤消息處理
if (errorRef) {
NSLog(@"ZMPersonModel to RecordRef error:%@", errorRef);
CFRelease(errorRef);
return NO;
}
return YES;
}
五. 通訊錄改變監聽
1. 註冊通訊錄變動監聽
// 註冊通訊錄變動的回調
ABAddressBookRegisterExternalChangeCallback(_addressBook, addressBookChangeCallBack, (__bridge_retained void *)(self));
2. 實現通訊錄變動監聽
/**
通訊錄聯繫人變動的回調
@param addressBook 註冊的addressBook
@param info 變動之後進行的回調方法
@param context 傳參,這裏是將自己作爲參數傳到方法中
*/
void addressBookChangeCallBack(ABAddressBookRef addressBook, CFDictionaryRef info, void *context)
{
// 清除緩存,重置addressBook
ABAddressBookRevert(addressBook);
}
3. 移除通訊錄變動監聽
// 移除監聽通訊錄變動的回調
ABAddressBookUnregisterExternalChangeCallback(_addressBook, addressBookChangeCallBack, (__bridge void *)(self));
六. Demo展示
1. Demo效果圖
2. Demo下載: https://github.com/zeng-zhiming/ZMAddressBook
原文地址:http://blog.csdn.net/zeng_zhiming/article/details/70141316