IOS获取通讯录联系人信息

IOS获取系统通讯录联系人信息

一、权限注册

随着apple对用户隐私的越来越重视,IOS系统的权限设置也更加严格,在获取系统通讯录之前,我们必须获得用户的授权。权限申请代码示例如下:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

    //这个变量用于记录授权是否成功,即用户是否允许我们访问通讯录

    int __block tip=0;

    //声明一个通讯簿的引用

    ABAddressBookRef addBook =nil;

    //因为在IOS6.0之后和之前的权限申请方式有所差别,这里做个判断

    if ([[UIDevice currentDevice].systemVersion floatValue]>=6.0) {

        //创建通讯簿的引用

        addBook=ABAddressBookCreateWithOptions(NULL, NULL);

        //创建一个出事信号量为0的信号

        dispatch_semaphore_t sema=dispatch_semaphore_create(0);

        //申请访问权限

        ABAddressBookRequestAccessWithCompletion(addBook, ^(bool greanted, CFErrorRef error)        {

            //greanted为YES是表示用户允许,否则为不允许

            if (!greanted) {

                tip=1;

            }

            //发送一次信号

            dispatch_semaphore_signal(sema);

        });

        //等待信号触发

         dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

    }else{

        //IOS6之前

        addBook =ABAddressBookCreate();

    }

    if (tip) {

    //做一个友好的提示

        UIAlertView * alart = [[UIAlertView alloc]initWithTitle:@"温馨提示" message:@"请您设置允许APP访问您的通讯录\nSettings>General>Privacy" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];

        [alart show];

        return;

    }

几点注意:1、dispatch_semaphore_t三个相关的操作为

                           dispatch_semaphore_create   创建一个信号
                    dispatch_semaphore_signal   发送一个信号
                    dispatch_semaphore_wait               等待信号触发    

                             dispatch_semaphore_create()创建一个信号,后面可以跟一个参数,表示信号量,当信号量正值时,dispatch_semaphore_wait后面的代码会被执行,否则程序将会一直等待在dispatch_semaphore_wait。 dispatch_semaphore_signal的作用是发送一个信号,会使信号量加1,相对的,dispatch_semaphore_wait执行后会使信号量减1.

                  2、因为是否被授权是在ABAddressBookRequestAccessWithCompletion的block回调中获取的,所以我们需要在外面做一个线程等待。

二、获取通讯录联系人详细信息

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

    //获取所有联系人的数组

    CFArrayRef allLinkPeople = ABAddressBookCopyArrayOfAllPeople(addBook);

    //获取联系人总数

    CFIndex number = ABAddressBookGetPersonCount(addBook);

    //进行遍历

    for (NSInteger i=0; i<number; i++) {

        //获取联系人对象的引用

        ABRecordRef  people = CFArrayGetValueAtIndex(allLinkPeople, i);

        //获取当前联系人名字

        NSString*firstName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonFirstNameProperty));

        //获取当前联系人姓氏

        NSString*lastName=(__bridge NSString *)(ABRecordCopyValue(people, kABPersonLastNameProperty));

        //获取当前联系人中间名

        NSString*middleName=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonMiddleNameProperty));

        //获取当前联系人的名字前缀

        NSString*prefix=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonPrefixProperty));

        //获取当前联系人的名字后缀

        NSString*suffix=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonSuffixProperty));

        //获取当前联系人的昵称

        NSString*nickName=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonNicknameProperty));

        //获取当前联系人的名字拼音

        NSString*firstNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonFirstNamePhoneticProperty));

        //获取当前联系人的姓氏拼音

        NSString*lastNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonLastNamePhoneticProperty));

        //获取当前联系人的中间名拼音

        NSString*middleNamePhoneic=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonMiddleNamePhoneticProperty));

        //获取当前联系人的公司

        NSString*organization=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonOrganizationProperty));

        //获取当前联系人的职位

        NSString*job=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonJobTitleProperty));

        //获取当前联系人的部门

        NSString*department=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonDepartmentProperty));

        //获取当前联系人的生日

        NSString*birthday=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonBirthdayProperty));

        NSMutableArray * emailArr = [[NSMutableArray alloc]init];

        //获取当前联系人的邮箱 注意是数组

        ABMultiValueRef emails= ABRecordCopyValue(people, kABPersonEmailProperty);

        for (NSInteger j=0; j<ABMultiValueGetCount(emails); j++) {

            [emailArr addObject:(__bridge NSString *)(ABMultiValueCopyValueAtIndex(emails, j))];

        }

        //获取当前联系人的备注

       NSString*notes=(__bridge NSString*)(ABRecordCopyValue(people, kABPersonNoteProperty));

       //获取当前联系人的电话 数组

        NSMutableArray * phoneArr = [[NSMutableArray alloc]init];

        ABMultiValueRef phones= ABRecordCopyValue(people, kABPersonPhoneProperty);

        for (NSInteger j=0; j<ABMultiValueGetCount(phones); j++) {

            [phonerr addObject:(__bridge NSString *)(ABMultiValueCopyValueAtIndex(phones, j))];

        }

        //获取创建当前联系人的时间 注意是NSDate

        NSDate*creatTime=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonCreationDateProperty));

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

        NSDate*alterTime=(__bridge NSDate*)(ABRecordCopyValue(people, kABPersonModificationDateProperty));

        //获取地址

        ABMultiValueRef address = ABRecordCopyValue(people, kABPersonAddressProperty);

        for (int j=0; j<ABMultiValueGetCount(address); j++) {

            //地址类型

            NSString * type = (__bridge NSString *)(ABMultiValueCopyLabelAtIndex(address, j));

            NSDictionary * temDic = (__bridge NSDictionary *)(ABMultiValueCopyValueAtIndex(address, j));

            //地址字符串,可以按需求格式化

            NSString * adress = [NSString stringWithFormat:@"国家:%@\n省:%@\n市:%@\n街道:%@\n邮编:%@",[temDic valueForKey:(NSString*)kABPersonAddressCountryKey],[temDic valueForKey:(NSString*)kABPersonAddressStateKey],[temDic valueForKey:(NSString*)kABPersonAddressCityKey],[temDic valueForKey:(NSString*)kABPersonAddressStreetKey],[temDic valueForKey:(NSString*)kABPersonAddressZIPKey]];

        }

        //获取当前联系人头像图片

        NSData*userImage=(__bridge NSData*)(ABPersonCopyImageData(people));

        //获取当前联系人纪念日

        NSMutableArray * dateArr = [[NSMutableArray alloc]init];

        ABMultiValueRef dates= ABRecordCopyValue(people, kABPersonDateProperty);

        for (NSInteger j=0; j<ABMultiValueGetCount(dates); j++) {

            //获取纪念日日期

            NSDate * data =(__bridge NSDate*)(ABMultiValueCopyValueAtIndex(dates, j));

            //获取纪念日名称

            NSString * str =(__bridge NSString*)(ABMultiValueCopyLabelAtIndex(dates, j));

            NSDictionary * temDic = [NSDictionary dictionaryWithObject:data forKey:str];

            [dateArr addObject:temDic];

        }

一点扩展:相同的方法,可以获取关联人信息,社交信息,邮箱信息,各种类型的电话信息,字段如下:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

 //相关人,组织字段

const ABPropertyID kABPersonKindProperty; 

const CFNumberRef kABPersonKindPerson;

const CFNumberRef kABPersonKindOrganization;

 

// 电话相关字段

AB_EXTERN const ABPropertyID kABPersonPhoneProperty;

AB_EXTERN const CFStringRef kABPersonPhoneMobileLabel;

AB_EXTERN const CFStringRef kABPersonPhoneIPhoneLabel 

AB_EXTERN const CFStringRef kABPersonPhoneMainLabel;

AB_EXTERN const CFStringRef kABPersonPhoneHomeFAXLabel;

AB_EXTERN const CFStringRef kABPersonPhoneWorkFAXLabel;

AB_EXTERN const CFStringRef kABPersonPhoneOtherFAXLabel

AB_EXTERN const CFStringRef kABPersonPhonePagerLabel;

 

// 即时聊天信息相关字段

AB_EXTERN const ABPropertyID kABPersonInstantMessageProperty;    

AB_EXTERN const CFStringRef kABPersonInstantMessageServiceKey;    

AB_EXTERN const CFStringRef kABPersonInstantMessageServiceYahoo;

AB_EXTERN const CFStringRef kABPersonInstantMessageServiceJabber;

AB_EXTERN const CFStringRef kABPersonInstantMessageServiceMSN;

AB_EXTERN const CFStringRef kABPersonInstantMessageServiceICQ;

AB_EXTERN const CFStringRef kABPersonInstantMessageServiceAIM;

AB_EXTERN const CFStringRef kABPersonInstantMessageServiceQQ 

AB_EXTERN const CFStringRef kABPersonInstantMessageServiceGoogleTalk;

AB_EXTERN const CFStringRef kABPersonInstantMessageServiceSkype;

AB_EXTERN const CFStringRef kABPersonInstantMessageServiceFacebook;

AB_EXTERN const CFStringRef kABPersonInstantMessageServiceGaduGadu;

AB_EXTERN const CFStringRef kABPersonInstantMessageUsernameKey; 

 

// 个人网页相关字段

AB_EXTERN const ABPropertyID kABPersonURLProperty;

AB_EXTERN const CFStringRef kABPersonHomePageLabel; 

//相关人姓名字段

AB_EXTERN const ABPropertyID kABPersonRelatedNamesProperty;   

AB_EXTERN const CFStringRef kABPersonFatherLabel;    // Father

AB_EXTERN const CFStringRef kABPersonMotherLabel;    // Mother

AB_EXTERN const CFStringRef kABPersonParentLabel;    // Parent

AB_EXTERN const CFStringRef kABPersonBrotherLabel;   // Brother

AB_EXTERN const CFStringRef kABPersonSisterLabel;    // Sister

AB_EXTERN const CFStringRef kABPersonChildLabel;      // Child

AB_EXTERN const CFStringRef kABPersonFriendLabel;    // Friend

AB_EXTERN const CFStringRef kABPersonSpouseLabel;    // Spouse

AB_EXTERN const CFStringRef kABPersonPartnerLabel;   // Partner

AB_EXTERN const CFStringRef kABPersonAssistantLabel; // Assistant

AB_EXTERN const CFStringRef kABPersonManagerLabel;   // Manager

三、通讯录“写”的相关操作

看到上面读取信息的代码,你可能觉得一阵目炫,其实只是字段比较长,逻辑还是很简单的,同样,写的操作与之类似,创建,修改,删除,是我们对通讯录“写”的常用操作。

1、创建一个联系人

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

    //创建一个联系人引用

    ABRecordRef person = ABPersonCreate();

    NSString *firstName = @"哈";

    NSString *lastName = @"哈";

    // 电话号码数组

    NSArray *phones = [NSArray arrayWithObjects:@"123",@"456",nil];

    // 电话号码对应的名称

    NSArray *labels = [NSArray arrayWithObjects:@"iphone",@"home",nil];

    //这里的字段和上面的字段完全相同

    // 设置名字属性

    ABRecordSetValue(person, kABPersonFirstNameProperty,(__bridge CFStringRef)firstName, NULL);

    // 设置姓氏属性

    ABRecordSetValue(person, kABPersonLastNameProperty, (__bridge CFStringRef)lastName, NULL);

    // 设置生日属性

    ABRecordSetValue(person, kABPersonBirthdayProperty,(__bridge CFDateRef)birthday, NULL);

    // 字典引用

    ABMultiValueRef dic =ABMultiValueCreateMutable(kABMultiStringPropertyType);

    // 添加电话号码与其对应的名称内容

    for (int i = 0; i < [phones count]; i ++) {

        ABMultiValueIdentifier obj = ABMultiValueAddValueAndLabel(dic,(__bridge CFStringRef)[phones objectAtIndex:i], (__bridge CFStringRef)[labels objectAtIndex:i], &obj);

    }

    // 设置phone属性

    ABRecordSetValue(person, kABPersonPhoneProperty, dic, NULL);

    // 将新建的联系人添加到通讯录中

    ABAddressBookAddRecord(addBook, person, NULL);

    // 保存通讯录数据

    ABAddressBookSave(addBook, NULL);

2、修改联系人

修改联系人的操作就是将获取和添加和在一起,先获取到相应的联系人引用,重设其属性字段即可。

3.删除联系人

?


1

2

3

4

5

6

7

8

9

10

11

12

13

     //获取所有联系人

     NSArray *array = (__bridge NSArray*)ABAddressBookCopyArrayOfAllPeople(addBook);

    // 遍历所有的联系人

    for (id obj in array) {

        ABRecordRef people = (__bridge ABRecordRef)obj;

        NSString *firstName = (__bridge NSString*)ABRecordCopyValue(people, kABPersonFirstNameProperty);

        NSString *lastName = (__bridge NSString*)ABRecordCopyValue(people, kABPersonLastNameProperty);

        if ([firstName isEqualToString:@"哈"] &&[lastName isEqualToString:@"哈"]) {

            ABAddressBookRemoveRecord(addBook, people,NULL);

        }

    }

    // 保存修改的通讯录对象

    ABAddressBookSave(addBook, NULL);

四、重中之重-关于内存管理

上面的代码为了演示方便,创建的全部引用都没有释放,势必是造成内存泄露,在我们用ABAddressBookCreate()创建一个引用对象时,切记无论ARC还MRC,要用CFRelease()进行释放引用,例如上面的例子,我们需要加上这句代码

CFRelease(addBook);

如果你耐心的看到了这里,我想你一定明白了我为什么不在前边的代码里说明这个问题,因为在ARC项目普及的现在,这的确是重中之重。

时间: 2024-12-03 20:52:37

IOS获取通讯录联系人信息的相关文章

详解iOS获取通讯录的4种方式_IOS

本文实例为大家分享了iOS获取通讯录的4种方式,供大家参考,具体内容如下 使用场景 一些App通过手机号码来推荐好友,如 微博.支付宝 首先客户端会获取通讯录中的所有手机号然后将这些手机号提交到App服务器中,服务器会查找每个手机号对应的App账号如QQ号码返回到客户端,然后客户端根据服务器返回的账号列表来推荐好友. 获取联系人方式 方案一:AddressBookUI.framework框架 提供了联系人列表界面.联系人详情界面.添加联系人界面等 一般用于选择联系人 方案二:AddressBoo

Android获取手机联系人信息_Android

Android如何获取手机联系人信息,本文为大家揭晓. 获取手机联系人信息步骤: 1.获取 ContentResolver ContentResolver resolver = getContentResolver(); 2.resolver.query(*)查询信息 查询手机联系人的URI:ContactsContract.RawContacts.CONTENT_URI 查询手机联系人手机号的URI:ContactsContract.CommonDataKinds.Phone.CONTENT_

设备-ios 获取蓝牙配对信息

问题描述 ios 获取蓝牙配对信息 有没有人做过IOS BLE 相关的应用,有一个问题,在IOS app里面怎么获取系统setting里面已经配对过的蓝牙设备的信息呢? 解决方案 http://www.raywenderlich.com/52080/introduction-core-bluetooth-building-heart-rate-monitor 解决方案二: 参考这篇老外的博客 介绍的是iphone通过蓝牙链接一台心跳检测仪,有详细介绍和代码 解决方案三: 参考这篇老外的博客 介绍

android利用ContentResolver访问者获取手机联系人信息

利用ContentResolver内容访问者,获取手机联系人信息我做了两种不同的做法.第一种,直接获取所有手机联系人信息,展示在ListView中.第二种,通过Butten按钮跳转到系统的手机联系人界面,单个获取手机联系人信息,展示在ListView中,结果如下: 第一种: 第二种: 第一种:直接获取所有手机联系人信息 首先需要在AndroidManifest.xml文件中添加权限: <uses-permission android:name="android.permission.REA

Android获取手机联系人信息

Android如何获取手机联系人信息,本文为大家揭晓. 获取手机联系人信息步骤: 1.获取 ContentResolver ContentResolver resolver = getContentResolver(); 2.resolver.query(*)查询信息 查询手机联系人的URI:ContactsContract.RawContacts.CONTENT_URI 查询手机联系人手机号的URI:ContactsContract.CommonDataKinds.Phone.CONTENT_

SNS网站中怎样获取MSN联系人信息

几乎所有的SNS网站都有[邀请站外好友]加入本站这个功能,当然,我们正在开发的这个名为XXX的网 站也不例外,今天学习了一下,把成果向大家做一简单汇报. 这个功能的关键点在于取得用户的已有联系人列表,并发送邀请函(一般都是电子邮件的形式),在 这篇文章里,只涉及怎么样取得MSN中联系人信息,如果大家有兴趣,我会把怎么样取得Gmail.Yahoo等 的联系人信息代码也都帖上来. 首先我想到的是参照已有网站的实现方式,如果开心网.校内网.FaceBook等. 开心网.校内网: 开心网和校内网的实现方

ios-iOS 获取通讯录后,可打印 输出结果只有一个联系人信息.

问题描述 iOS 获取通讯录后,可打印 输出结果只有一个联系人信息. 打印self.allPerson可以打印出所有联系人信息, 可是打印self.allPeople时,什么结果也没有输出.????? #import "AddressBook.h" #import "pinyin.h"//将汉字转换成英文 #import "Person.h"//将联系人信息存储成一个一个的person //存储通讯录的类 @interface AddressBo

iOS访问通讯录开发:读取联系人信息

iOS读取通信录中的联系人一般的过程是先查找联系人记录,然后再访问记录的属性,属性又可以分为单值 属性和多值属性.通过下面例子介绍联系人的查询,以及单值属性和多值属性的访问,还有读取联系人中的图 片数据. 开发:读取联系人信息-"> 本案例是从iOS设备上读取通讯 录中的联系人,并将其显示在一个表视图中,可以进行查询,点击联系人进入详细信息画面.访问通讯录的应 用必须要做的两件事情: 1.添加AddressBook和AddressBookUI框架 为工程添加 AddressBook.fra

Android获取手机联系人的方法

Android 获取系统联系人信息的实例 一.获取手机联系人姓名及手机号 //跳转到系统联系人应用 Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI); try { startActivityForResult(intent, Contacts1RequestCode); } catch (Exception e) { LogManager.e("打开联系人信息失败"