当前位置: 首页 > news >正文

通讯录--(适配iOS7/8/9)

导入库#import <AddressBook/AddressBook.h>

         #import <AddressBookUI/AddressBookUI.h>

#pragma mark  点击 弹出通讯录

 

- (IBAction)contactClicked:(id)sender {

    //1. 创建联系人选择控制器

    ABPeoplePickerNavigationController *picker = [ABPeoplePickerNavigationController new];

    //2. 设置代理,注意不是 Delegate

    picker.peoplePickerDelegate = self;

    //3. 模态视图弹出

    [self presentViewController:picker animated:YES completion:nil];

    

    //iOS 8之后如不想自动dismiss可以在弹出联系人控制器方法中加入如下代码:

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

        picker.predicateForSelectionOfPerson = [NSPredicate predicateWithValue:false];

    }

    

    

}

#pragma mark  代理方法介绍 

//注意:  iOS7 iOS8 的代理方法必须都写出来,这样才可以适配7 8

//以下12两个代理方法,如果同时实现, 只会运行第一个方法!

//1.第一个代理方法:选中某个联系人时调用(iOS8之后实现后再无法调用第2个的方法)

//参数 (ABRecordRef)person 介绍:

//一个联系人就是一个ABRecordRef对象,就相当于一条记录,每个联系人都有自己的属性,比如名字、电话、邮件等,使用ABRecordCopyValue函数可以从ABRecordRef中获得联系人的简单属性(参见下面简单属性的介绍)

//ABRecordCopyValue 从记录中取值函数:

//CFTypeRef ABRecordCopyValue(ABRecordRef record, ABPropertyID property)

//2个参数:

//1个参数是ABRecordRef实例

//2个参数ABPropertyID是属性关键字,定义在ABPerson.h中,下面有介绍

//注意:使用ABRecordCopyValue可以从一条Person记录中获取到对应的值,但是后续还需要根据值的具体类型再加以处理(比如简单属性取的值不需要再处理,多重属性的值还需要通过其它函数再取值)

//ABPropertyID联系人属性介绍

//ABPropertyID 就是联系人的属性,所有的属性常量值都定义在了ABPerson.h头文件中

//联系人属性包括以下类型:

//1)简单属性:姓 kABPersonLastNameProperty,名 kABPersonFirstNameProperty

//2)组合属性:地址等 kABPersonAddressProperty

//3)多重属性:电话号码 kABPersonPhoneProperty 、电子邮件 kABPersonEmailProperty

//联系人的有些属性值就没这么简单,一个属性可能会包含多个值,比如邮箱,分为工作邮箱、住宅邮箱、其他邮箱等,比如电话,分为工作电话、住宅电话、其他电话等

//如果是多重属性,那么ABRecordCopyValue函数返回的就是ABMultiValueRef类型的数据,例如邮箱或者电话

取电话号码

//ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);

取记录数量

//NSInteger phoneCount = ABMultiValueGetCount(phones);

遍历所有的电话号码

//for (NSInteger i = 0; i < phoneCount; i++) {...}

//获取多重属性的方法

电话标签

//CFStringRef phoneLabel = ABMultiValueCopyLabelAtIndex(phones, i);

本地化电话标签

//CFStringRef phoneLocalLabel = ABAddressBookCopyLocalizedLabel(phoneLabel);

电话号码

//CFStringRef phoneNumber = ABMultiValueCopyValueAtIndex(phones, i);

 

 

 

#pragma mark   代理

- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person{

    //例子1:从记录中取姓,并转换为NSString类型

    

    CFStringRef lastName = ABRecordCopyValue(person, kABPersonLastNameProperty);

    NSString *lastNameStr = (__bridge NSString *)(lastName);

    CFRelease(lastName); // 使用__bridge type 方法记得释放!

    

    

    //例子2:获取电话号码, 电话返回的是多数据类型(可以获取到标签和电话号等信息)

    // 获取电话,电话是多数据类型

    ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);

    // 获取电话的个数

    CFIndex count = ABMultiValueGetCount(phones);

    // 遍历联系人,取出每个电话标签和电话号码,CF框架必须用for i循环

    for (CFIndex i = 0 ; i < count; i++) {

        // 获取联系电话的标签,使用__bridge_transfer方法不用释放

        NSString *label = (__bridge_transfer NSString *)ABMultiValueCopyLabelAtIndex(phones,  i);

        NSLog(@"label: %@",label);

        // 获取联系电话,使用CFBridgingRelease方法和上面功能一样也不需要释放

        NSString *value = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones,  i));

        NSLog(@"value: %@",value);

    }

    //phones 对象需要被释放

    CFRelease(phones);

    

}

 

//例子3:获取通讯录中所有联系人信息

 

//- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person {

//    // 1. 获取系统通讯录应用

//    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, nil);

//    // 2. 获取所有联系人记录

//    NSArray *array = (__bridge_transfer NSArray *)(ABAddressBookCopyArrayOfAllPeople(addressBook));

//    for (NSInteger i = 0; i < array.count; i++) {

//        // 取出一条记录

//        ABRecordRef person = (__bridge ABRecordRef)(array[i]);

//        // 取出个人记录中的详细信息

//        NSString *firstNameLabel = (__bridge_transfer NSString *)(ABPersonCopyLocalizedPropertyName(kABPersonFirstNameProperty));

//        NSString *firstName = (__bridge_transfer NSString *)(ABRecordCopyValue(person, kABPersonFirstNameProperty));

//        NSString *lastNameLabel =(__bridge_transfer NSString *)(ABPersonCopyLocalizedPropertyName(kABPersonLastNameProperty));

//        NSString *lastName =(__bridge_transfer NSString *)(ABRecordCopyValue(person, kABPersonLastNameProperty));

//        NSLog(@"%@ %@ - %@ %@", lastNameLabel, lastName, firstNameLabel, firstName);

//    }

//    CFRelease(addressBook);

//}

 

 

 

//关于Core Foundation NSFundation 桥接的问题:

//注意:无论CF对象是否被引用,只要使用CF函数,就会产生CF对象留在内存中,如:ABMultiValueCopyValueAtIndex(phones, i)这一句,建议点击静态内存分析工具,可发现没有被释放的CF对象。

//桥接有三种方式:

//

//(__bridge type)expression) : 只是让NSFoundation框架暂时使用CF框架对象,注意需要手动释放 Core Foundation 对象,用CFRelease( )函数。

//(__bridge_transfer type)expression) / CFBridgingReleaseexpression) : CF框架移交对象的管理权给NSFoundation框架,不需要手动释放对象

//前两种是将CF对象转NSFoundation,最后一个是NSFoundation CF对象,不常用

//(__bridge_retained <#CF type#>)(<#expression#>)

 

 

 

 

//2.第二个代理方法,选中联系人某个属性(详细的信息,如电话号码)的时候调用,注意和上面的方法只能实现一个,如同时实现无法跳转到联系人详情页面,优先上面的方法

//该方法可以获取具体的哪个电话号码,例如使用(充值话费)时不能使用上面方法,因为无法确定具体充值哪个号码

 

#pragma mark 选中联系人的某个属性的时候调用

- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {

    // 获取该联系人多重属性--电话号

    ABMutableMultiValueRef phoneMulti = ABRecordCopyValue(person, kABPersonPhoneProperty);

    

    // 获取该联系人的名字,简单属性,只需ABRecordCopyValue取一次值

    ABMutableMultiValueRef firstName = ABRecordCopyValue(person, kABPersonFirstNameProperty);

    NSString *name = (__bridge NSString *)(firstName);

    // 获取点击的联系人的电话

    NSLog(@"联系人名字 %@",name);

    

    // 点击某个联系人电话后dismiss联系人控制器,并回调点击的数据

    [self dismissViewControllerAnimated:YES completion:^{

        // 从多重属性——电话号中取值,参数2是取点击的索引

        NSString *aPhone =  (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phoneMulti, ABMultiValueGetIndexForIdentifier(phoneMulti,identifier)) ;

        // 获取点击的联系人的电话,也可以取标签等

        NSLog(@"联系人电话 %@",aPhone);

        // 去掉电话号中的 "-"

        aPhone = [aPhone stringByReplacingOccurrencesOfString:@"-" withString:@"" ];

        NSLog(@"去掉- %@",aPhone);

    }];

}

 

 

 

//4.下面两个是  iOS7  选择联系人代理方法,iOS 8之前才会调用,适配iOS 7时实现,适配iOS 8之后使用上面两个方法

//1.返回YES,则会跳转到联系人详情页面,如果返回NO必须手动实现控制器dismiss方法

//- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person NS_DEPRECATED_IOS(2_0, 8_0);

//2.返回NO不会执行默认的操作,如:打电话,必须手动实现控制器dismiss方法

//- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier NS_DEPRECATED_IOS(2_0, 8_0);

 

 

 

 

转载于:https://www.cnblogs.com/daxueshan/p/5844009.html

相关文章:

  • delphi关键字
  • JavaScript之面向对象学习五(JS原生引用类型Array、Object、String等等)的原型对象介绍...
  • Bootstrap结合BootstrapTable的使用,分为两种模试显示列表。 自适应表格,自定义行列...
  • Zabbix监控之Redis自动发现并监控(python)
  • SQLServer · 特性分析 · SQL Server 2012的分析函数未必都理解透了(1)
  • 重定向Http status code 303 和 302
  • 输入一组数组,回车结束
  • Java反射在JVM的实现
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)...
  • jdbc conn.commit()提交事务和 rollback()使用
  • 每天一个linux命令:mkdir命令
  • 程序(进程)内存分布解析【转】
  • jenkins updatecenter更新插件有问题
  • Django+uwsgi+Nginx安装部署
  • hexo+github搭建个人博客
  • 2017年终总结、随想
  • CentOS 7 修改主机名
  • C语言笔记(第一章:C语言编程)
  • Joomla 2.x, 3.x useful code cheatsheet
  • js递归,无限分级树形折叠菜单
  • python docx文档转html页面
  • Service Worker
  • vuex 笔记整理
  • 从setTimeout-setInterval看JS线程
  • 分布式任务队列Celery
  • 聚簇索引和非聚簇索引
  • 入门到放弃node系列之Hello Word篇
  • 我的zsh配置, 2019最新方案
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 在weex里面使用chart图表
  • python最赚钱的4个方向,你最心动的是哪个?
  • 大数据全解:定义、价值及挑战
  • ​你们这样子,耽误我的工作进度怎么办?
  • ​人工智能书单(数学基础篇)
  • #etcd#安装时出错
  • %@ page import=%的用法
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (2)STM32单片机上位机
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (Python第六天)文件处理
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • ******之网络***——物理***
  • .chm格式文件如何阅读
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .NET Core跨平台微服务学习资源
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .net Signalr 使用笔记
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .NET上SQLite的连接
  • .NET学习全景图
  • //解决validator验证插件多个name相同只验证第一的问题