AddressBook是Apple提供给我们获取系统联系人的一个很方便类库,与其说方便,其实刚开始还是比较崩溃的,从开发文档来看,它还是偏向于C语言,并且不在ARC的控制之下,虽然在iOS9.0之后会被Contacts.framework替代,但在工作中要对最低版本进行兼容,了解一下这个类库还是很有必要的。这里就介绍一下获取联系人信息的那些方法,对于修改,添加删除等操作,想留在下一篇介绍AddressBookUI这个类库的时候来写一下。

代码GitHub:https://github.com/YRunIntoLove/YAdressBookDemo

获取权限

iOS6.0之后,苹果对于用户隐私就加强了,所有调用系统权限都需要用户授权才可以进行之后的操作,因此在获取通讯录的时候要检测一下有没有权限(这一点在定位,相机等操作上也都看出):

/***  检测权限并作响应的操作*/
- (void)checkAuthorizationStatus
{switch (ABAddressBookGetAuthorizationStatus()){//存在权限case kABAuthorizationStatusAuthorized://获取通讯录[self obtainContacts:self.addressBook];break;//权限未知case kABAuthorizationStatusNotDetermined://请求权限[self requestAuthorizationStatus];break;//如果没有权限case kABAuthorizationStatusDenied:case kABAuthorizationStatusRestricted://需要提示//弹窗提醒[self showAlertController];break;default:break;}
}

请求权限的方法如下:

/***  请求通讯录的权限*/
- (void)requestAuthorizationStatus
{//避免强引用__weak typeof(self) copy_self = self;ABAddressBookRequestAccessWithCompletion(self.addressBook, ^(bool granted, CFErrorRef error) {//权限得到允许if (granted == true){//主线程获取联系人dispatch_async(dispatch_get_main_queue(), ^{[copy_self obtainContacts:self.addressBook];});}});
}

请求联系人列表

为Demo中是楼主自行构建的Model,因此代码就显得简略了好多,后面会附上CFRecord转模型的代码:

/***  获取通讯录中的联系人*/
- (void)obtainContacts:(ABAddressBookRef)addressBook
{//按照添加时间请求所有的联系人CFArrayRef contants = ABAddressBookCopyArrayOfAllPeople(addressBook);//按照排序规则请求所有的联系人
//    ABRecordRef recordRef = ABAddressBookCopyDefaultSource(addressBook);//这里的firstName是按照姓名属性中的firstName来排序的,并不是按照全称来排序
//    CFArrayRef contants = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, recordRef, kABPersonSortByFirstName);//存放所有联系人的数组NSMutableArray <YContactObject *> * contacts = [NSMutableArray arrayWithCapacity:0];//遍历获取所有的数据for (NSInteger i = 0; i < CFArrayGetCount(contants); i++){//获得People对象ABRecordRef recordRef = CFArrayGetValueAtIndex(contants, i);//获得contact对象YContactObject * contactObject = [YContactObjectManager contantObject:recordRef];//添加对象[contacts addObject:contactObject];}//释放资源,因为不在ARC下,retain或者copy之后记得releaseCFRelease(contants);//进行回调赋值ContactDidObatinBlock copyBlock  = self.contactsDidObtainBlockHandle;//进行数据回调copyBlock([NSArray arrayWithArray:contacts]);
}

获取联系人的姓名属性

为了让代码可读性更好一点,在进行转型的时候写了如下方法,是为了方便将CFStringRef通过桥接__bridge转型成NSString对象:

/***  根据属性key获得NSString**  @param property 属性key*/
+ (NSString *)contactProperty:(ABPropertyID) property
{return (__bridge NSString *)(ABRecordCopyValue(self.recordRef, property));
}

获取姓名相关属性方法如下:

/***  获得姓名的相关属性*/
+ (YContactNameObject *)contactNameProperty
{//初始化对象YContactNameObject * nameObject = [[YContactNameObject alloc]init];nameObject.givenName = [self contactProperty:kABPersonFirstNameProperty];                   //名字nameObject.familyName = [self contactProperty:kABPersonLastNameProperty];                   //姓氏nameObject.middleName = [self contactProperty:kABPersonMiddleNameProperty];                 //名字中的信仰名称(比如Jane·K·Frank中的K)nameObject.namePrefix = [self contactProperty:kABPersonPrefixProperty];                     //名字前缀nameObject.nameSuffix = [self contactProperty:kABPersonSuffixProperty];                     //名字后缀nameObject.nickName = [self contactProperty:kABPersonNicknameProperty];                     //名字昵称nameObject.phoneticGivenName = [self contactProperty:kABPersonFirstNamePhoneticProperty];   //名字的拼音音标nameObject.phoneticFamilyName = [self contactProperty:kABPersonLastNamePhoneticProperty];   //姓氏的拼音音标nameObject.phoneticMiddleName = [self contactProperty:kABPersonMiddleNamePhoneticProperty]; //英文信仰缩写字母的拼音音标return nameObject;
}

获取联系人的类型

/***  获得联系人类型信息*/
+ (YContactType)contactTypeProperty
{//获得类型属性CFNumberRef typeIndex = ABRecordCopyValue(self.recordRef, kABPersonKindProperty);//表示是公司联系人if (CFNumberCompare(typeIndex, kABPersonKindOrganization, nil) == kCFCompareEqualTo){//释放资源CFRelease(typeIndex);return YContactTypeOrigination;}return YContactTypePerson;
}

获取联系人的头像图片

/***  获得联系人的头像图片*/
+ (UIImage *)contactHeadImagePropery
{//首先判断是否存在头像if (ABPersonHasImageData(self.recordRef) == false)//没有头像,返回nil{return nil;}//开始获得头像信息NSData * imageData = (__bridge NSData *)(ABPersonCopyImageData(self.recordRef));//获得头像原图
//    NSData * imageData = CFBridgingRelease(ABPersonCopyImageDataWithFormat(self.recordRef, kABPersonImageFormatOriginalSize));return [UIImage imageWithData:imageData];
}

获取联系人的电话信息

/***  获得电话号码对象数组*/
+ (NSArray <YContactPhoneObject *> *)contactPhoneProperty
{//外传数组NSMutableArray <YContactPhoneObject *> * phones = [NSMutableArray arrayWithCapacity:0];//获得电话号码的多值属性ABMultiValueRef values = ABRecordCopyValue(self.recordRef, kABPersonPhoneProperty);for (NSInteger i = 0; i < ABMultiValueGetCount(values); i++){YContactPhoneObject * phoneObject = [[YContactPhoneObject alloc]init];//开始赋值phoneObject.phoneTitle = (__bridge NSString *)ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(values, i)); //电话描述(如住宅、工作..)phoneObject.phoneNumber = (__bridge NSString *)ABMultiValueCopyValueAtIndex(values, i);                                 //电话号码//添加数据[phones addObject:phoneObject];}//释放资源CFRelease(values);return [NSArray arrayWithArray:phones];
}

获取联系人的工作信息

/***  获得工作的相关属性*/
+ (YContactJobObject *)contactJobProperty
{YContactJobObject * jobObject = [[ YContactJobObject alloc]init];jobObject.organizationName = [self contactProperty:kABPersonOrganizationProperty]; //公司(组织)名称jobObject.departmentName = [self contactProperty:kABPersonDepartmentProperty];     //部门jobObject.jobTitle = [self contactProperty:kABPersonJobTitleProperty];             //职位return jobObject;
}

获取联系人的邮件信息

/***  获得Email对象的数组*/
+ (NSArray <YContactEmailObject *> *)contactEmailProperty
{//外传数组NSMutableArray <YContactEmailObject *> * emails = [NSMutableArray arrayWithCapacity:0];//获取多值属性ABMultiValueRef values = ABRecordCopyValue(self.recordRef, kABPersonEmailProperty);//遍历添加for (NSInteger i = 0; i < ABMultiValueGetCount(values); i++){YContactEmailObject * emailObject = [[YContactEmailObject alloc]init];emailObject.emailTitle = (__bridge NSString *)(ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(values, i)));  //邮件描述emailObject.emailAddress = (__bridge NSString *)(ABMultiValueCopyValueAtIndex(values, i));                                 //邮件地址//添加[emails addObject:emailObject];}//释放资源CFRelease(values);return [NSArray arrayWithArray:emails];
}

获取联系人的地址信息

/***  获得Address对象的数组*/
+ (NSArray <YContactAddressObject *> *)contactAddressProperty
{//外传数组NSMutableArray <YContactAddressObject *> * addresses = [NSMutableArray arrayWithCapacity:0];//获取多指属性ABMultiValueRef values = ABRecordCopyValue(self.recordRef, kABPersonAddressProperty);//遍历添加for (NSInteger i = 0; i < ABMultiValueGetCount(values); i++){YContactAddressObject * addressObject = [[YContactAddressObject alloc]init];//赋值addressObject.addressTitle = (__bridge NSString *)ABAddressBookCopyLocalizedLabel((ABMultiValueCopyLabelAtIndex(values, i)));                    //地址标签//获得属性字典NSDictionary * dictionary = (__bridge NSDictionary *)ABMultiValueCopyValueAtIndex(values, i);//开始赋值addressObject.country = [dictionary valueForKey:(__bridge NSString *)kABPersonAddressCountryKey];               //国家addressObject.city = [dictionary valueForKey:(__bridge NSString *)kABPersonAddressCityKey];                     //城市addressObject.state = [dictionary valueForKey:(__bridge NSString *)kABPersonAddressStateKey];                   //省(州)addressObject.street = [dictionary valueForKey:(__bridge NSString *)kABPersonAddressStreetKey];                 //街道addressObject.postalCode = [dictionary valueForKey:(__bridge NSString *)kABPersonAddressZIPKey];                //邮编addressObject.ISOCountryCode = [dictionary valueForKey:(__bridge NSString *)kABPersonAddressCountryCodeKey];    //ISO国家编号//添加数据[addresses addObject:addressObject];}//释放资源CFRelease(values);return [NSArray arrayWithArray:addresses];}

获取联系人的生日信息

/***  根据属性key获得NSDate**  @param property 属性key**  @return NSDate对象*/
+ (NSDate *)contactDateProperty:(ABPropertyID) property
{return (__bridge NSDate *)(ABRecordCopyValue(self.recordRef, property));
}/***  获得生日的相关属性*/
+ (YContactBrithdayObject *)contactBrithdayProperty
{//实例化对象YContactBrithdayObject * brithdayObject = [[YContactBrithdayObject alloc]init];//生日的日历brithdayObject.brithdayDate = [self contactDateProperty:kABPersonBirthdayProperty];         //生日的时间对象//获得农历日历属性的字典NSDictionary * brithdayDictionary = (__bridge NSDictionary *)(ABRecordCopyValue(self.recordRef, kABPersonAlternateBirthdayProperty));//农历日历的属性,设置为农历属性的时候,此字典存在数值if (brithdayDictionary != nil){brithdayObject.calendar = [brithdayDictionary valueForKey:@"calendar"];                                 //农历生日的标志位,比如“chinese”//农历生日的相关存储属性brithdayObject.era = [(NSNumber *)[brithdayDictionary valueForKey:@"era"] integerValue];                //纪元,六十组干支纪年的索引数,比如12年为壬辰年,为循环的29,此数字为29brithdayObject.year = [(NSNumber *)[brithdayDictionary valueForKey:@"year"] integerValue];              //年份brithdayObject.month = [(NSNumber *)[brithdayDictionary valueForKey:@"month"] integerValue];            //月份brithdayObject.leapMonth = [(NSNumber *)[brithdayDictionary valueForKey:@"isLeapMonth"] boolValue];     //是否是闰月brithdayObject.day = [(NSNumber *)[brithdayDictionary valueForKey:@"day"] integerValue];                //日期}//返回对象return brithdayObject;
}

获取联系人的即时通信信息

/***  获得即时通信账号相关信息*/
+ (NSArray <YContactInstantMessageObject *> *)contactMessageProperty
{//存放数组NSMutableArray <YContactInstantMessageObject *> * instantMessages = [NSMutableArray arrayWithCapacity:0];//获取数据字典ABMultiValueRef messages = ABRecordCopyValue(self.recordRef, kABPersonInstantMessageProperty);//遍历获取值for (NSInteger i = 0; i < ABMultiValueGetCount(messages); i++){//获取属性字典NSDictionary * messageDictionary = CFBridgingRelease(ABMultiValueCopyValueAtIndex(messages, i));//实例化YContactInstantMessageObject * instantMessageObject = [[YContactInstantMessageObject alloc]init];instantMessageObject.service = [messageDictionary valueForKey:@"service"];          //服务名称(如QQ)instantMessageObject.userName = [messageDictionary valueForKey:@"username"];        //服务账号(如QQ号)//添加[instantMessages addObject:instantMessageObject];}return [NSArray arrayWithArray:instantMessages];
}

获得联系人的关联人信息

/***  获得联系人的关联人信息*/
+ (NSArray <YContactRelatedNamesObject *> *)contactRelatedNamesProperty
{//存放数组NSMutableArray <YContactRelatedNamesObject *> * relatedNames = [NSMutableArray arrayWithCapacity:0];//获得多值属性ABMultiValueRef names = ABRecordCopyValue(self.recordRef, kABPersonRelatedNamesProperty);//遍历赋值for (NSInteger i = 0; i < ABMultiValueGetCount(names); i++){//初始化YContactRelatedNamesObject * relatedName = [[YContactRelatedNamesObject alloc]init];//赋值relatedName.relatedTitle = CFBridgingRelease(ABAddressBookCopyLocalizedLabel(ABMultiValueCopyLabelAtIndex(names, i))); //关联的标签(如friend)relatedName.relatedName = CFBridgingRelease(ABMultiValueCopyValueAtIndex(names, i));                                    //关联的名称(如联系人姓名)//添加[relatedNames addObject:relatedName];}return [NSArray arrayWithArray:relatedNames];
}

获取联系人的社交简介信息

/***  获得联系人的社交简介信息*/
+ (NSArray <YContactSocialProfileObject *> *)contactSocialProfilesProperty
{//外传数组NSMutableArray <YContactSocialProfileObject *> * socialProfiles = [NSMutableArray arrayWithCapacity:0];//获得多值属性ABMultiValueRef profiles = ABRecordCopyValue(self.recordRef, kABPersonSocialProfileProperty);//遍历取值for (NSInteger i = 0; i < ABMultiValueGetCount(profiles); i++){//初始化对象YContactSocialProfileObject * socialProfileObject = [[YContactSocialProfileObject alloc]init];//获取属性值NSDictionary * profileDictionary = CFBridgingRelease(ABMultiValueCopyValueAtIndex(profiles, i));//开始赋值socialProfileObject.socialProfileTitle = [profileDictionary valueForKey:@"service"];    //社交简介(如sinaweibo)socialProfileObject.socialProFileAccount = [profileDictionary valueForKey:@"username"]; //社交地址(如123456)socialProfileObject.socialProFileUrl = [profileDictionary valueForKey:@"url"];          //社交链接的地址(按照上面两项自动为http://weibo.com/n/123456)//添加[socialProfiles addObject:socialProfileObject];   }return [NSArray arrayWithArray:socialProfiles];
}

获取联系人的备注信息

//备注
contactObject.note = [self contactProperty:kABPersonNoteProperty];               

获取联系人的创建时间

//创建时间
contactObject.creationDate = [self contactDateProperty:kABPersonCreationDateProperty];

获取联系人的最近修改时间

//最近一次修改的时间
contactObject.modificationDate = [self contactDateProperty:kABPersonModificationDateProperty];

接收外界通讯录发生变化的方法

在初始化AddressBook的时候为它注册一个通知

//创建一个AddressBook
self.addressBook = ABAddressBookCreate();/***  注册通讯录变动的回调**  @param self.addressBook          注册的addressBook*  @param addressBookChangeCallBack 变动之后进行的回调方法*  @param void                      传参,这里是将自己作为参数传到方法中,*  将自己传过去的时候,一定要用__bridge_retained一下,如果不retained,会发生内存泄露,计数器不正确,导致程序崩溃*/
ABAddressBookRegisterExternalChangeCallback(self.addressBook,  addressBookChangeCallBack, (__bridge_retained void *)(self));

在外面自己写回调的方法,这个方法是外界的通讯录发生增删改查之后,再次回到此App的时候才会触发的方法

void addressBookChangeCallBack(ABAddressBookRef addressBook, CFDictionaryRef info, void *context)
{//coding when addressBook did changedNSLog(@"通讯录发生变化啦");//初始化对象,这里是将参数转成对象的方法YContactsManager * contactManager = CFBridgingRelease(context);}

iOS开发------获取系统联系人(AddressBook篇)相关推荐

  1. IOS开发调用系统相机和打开闪光灯

    IOS开发调用系统相机和打开闪光灯      今天给大家分享一下如何调用iphone的拍照功能和打开闪光灯,有些代码我也不太理解,很多是在网上借鉴其他人的.IOS有两种的拍照和视频的方式:1.直接使用 ...

  2. IOS开发—— 获取AppDelegate的属性或字段

    IOS开发-- 获取AppDelegate的属性或字段 其它控制器中: AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplicat ...

  3. IOS开发高手课第三篇 App Auto Layout 是怎么进行自动布局的,性能如何?

    03 | Auto Layout 是怎么进行自动布局的,性能如何? Auto Layout ,是苹果公司提供的一个基于约束布局,动态计算视图大小和位置的库,并且已经集成到了 Xcode 开发环境里. ...

  4. iOS开发——网络使用技术OC篇网络爬虫-使用正则表达式抓取网络数据

    网络爬虫-使用正则表达式抓取网络数据 关于网络数据抓取不仅仅在iOS开发中有,其他开发中也有,也叫网络爬虫,大致分为两种方式实现 1:正则表达 2:利用其他语言的工具包:java/Python 先来看 ...

  5. iOS开发 获取设备参数

    在开发的过程中我们经常要获取设备的参数的参数,比如设备的机型,设备的系统版本,以及设备的电量等,下面我把这些做了一个整理放到了一个类里面! .h文件 #import <Foundation/Fo ...

  6. iOS实现获取系统iTunes音乐的方法示例

    这篇文章主要给大家介绍了关于iOS如何实现获取系统iTunes音乐的相关资料,文中通过示例代码给大家详细介绍了实现的方法,并给大家介绍了MPMediaPickerController的相关知识,对大家 ...

  7. Api demo源码学习(8)--App/Activity/QuickContactsDemo --获取系统联系人信息

    本节通过Content Provider机制获取系统中的联系人信息,注意这个Anctivity直接继承的是ListActivity,所以不再需要setContentView函数来加载布局文件了(我自己 ...

  8. iPhone开发 获取系统时间 星期 年 月 日 时 分 秒

    //获取系统当前时间 - (NSString*)get_system_today_time { NSDate *date = [NSDate date]; NSDateFormatter *forma ...

  9. 安卓简单开发-获取系统时间

    安卓获取系统时间. 本人只了解三种获取系统时间的方式: 第一种方式:  Calendar Calendar c=Calendar.getInstance(); //取得系统日期 -年月日     in ...

最新文章

  1. 解决plsql中文显示问号(???)问题
  2. 某团技术拷问:ArrayList 和 LinkedList 哪个更占空间?
  3. IAR编译器的常见问题
  4. mybatis映射器${}和#{}的区别
  5. oracle适配器接口,Oracle
  6. UML分析AsyncDisplayKit框架-ASMuplexImageNode异步下载时序图。
  7. snmp 获得硬件信息_信息系统项目管理师(三)
  8. Qt实践| HTTP知识点-接入某图片验证码系统识别验证码
  9. 设计灵感|如何让你的海报更具现代感?
  10. onConfigurationChanged方法的使用
  11. MATLAB 数学应用 微分方程 常微分方程 选择ODE求解器
  12. opencv-python学习笔记-2对比度增强——研0基础学习
  13. 百度杀毒+7654联盟
  14. 爱酱,鹿鸣?!自己怎么做一个虚拟二次元偶像?
  15. 免费多功能转码机器人(小程序转码机器人)
  16. 【TensorFlow基础操作笔记】图+对话+张量+变量+线性回归实例
  17. 显示器会影响电脑的显示效果么
  18. Layabox 实现画 刚体线
  19. 著名弹跳训练法 练成可提高30cm
  20. 安卓 build.prop 进行修改提高性能

热门文章

  1. 5G物联网设备,防止黑客入侵是首要问题
  2. 计算机total函数,Excel中怎样用subtotal函数计算总值
  3. ZOJ 1204 Additive equations
  4. 给出一个 netdump 程序, 抓包用的. 如果改进了,也希望贴出(摘自Chinaunix-论坛首页-C/C++)
  5. 共享经济时代,逸管家联合体集团引领中小企业走向辉煌
  6. opencv读取摄像头数据有黑边
  7. Ubuntu删除Steam
  8. 电子信息工程求职目标_20届,上海科技大学电子信息工程专业,大三的他如何拿下复星集团的产品offer?未来目标是大厂!...
  9. 计算机模拟管道应力分析实验报告,水力学实验报告答案解析.doc
  10. PDF编辑器中文版功能有什么 如何添加PDF水印