iOS开发学习-类似微信聊天消息中的电话号码点击保存到通讯录中的功能
类似微信聊天消息中的电话号码点击保存到通讯录中的功能,ABAddress的实现在iOS9中是不能正常使用的,点击完成后,手机会非常的卡,iOS9之后需要使用Contact新提供的方法来实现该功能。快捷保存手机号码到系统通讯录中的需求在很多的应用中都会用的到,QQ、微信等社交软件都是可以见到的,虽然实现起来也是很简单的,小编还是把这个小功能整理一下,方便后面在需要的时候能方便的使用,也能方便朋友们能感到方便。有需要的直接可以拿去,甚是方便,废话不多说,代码已经上传Github:https://github.com/Gjianhao/JHContacts
ViewController.h
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
#import <Contacts/Contacts.h>
#import <ContactsUI/ContactsUI.h> @interface ViewController : UIViewController<UIActionSheetDelegate,ABNewPersonViewControllerDelegate,ABPeoplePickerNavigationControllerDelegate,CNContactPickerDelegate,CNContactViewControllerDelegate> @property (nonatomic, strong)CNContactViewController *controller; @end
ViewController.m
#import "ViewController.h" #define iOS7Later ([UIDevice currentDevice].systemVersion.floatValue >= 7.0f)
#define iOS8Later ([UIDevice currentDevice].systemVersion.floatValue >= 8.0f)
#define iOS9Later ([UIDevice currentDevice].systemVersion.floatValue >= 9.0f)
#define iOS9_1Later ([UIDevice currentDevice].systemVersion.floatValue >= 9.1f) @interface ViewController (){
NSString *linkMobile;
}
/**
* 电话号码
*/
@property (nonatomic, weak) IBOutlet UIButton *btnNum; - (IBAction)btnNumClick:(id)sender; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
} - (IBAction)btnNumClick:(id)sender {
linkMobile = _btnNum.titleLabel.text;
NSString *title = [NSString stringWithFormat:@"%@可能是一个电话号码,你可以",linkMobile];
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:title delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"呼叫",@"添加到手机通讯录", nil];
actionSheet.tag=;
[actionSheet showInView:self.view];
}
#pragma mark - UIActionSheetDelegate
-(void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex{
if (actionSheet.tag==) {
if(buttonIndex==){
NSURL *tmpUrl=[NSURL URLWithString:[NSString stringWithFormat:@"telprompt://%@",linkMobile]];
[[UIApplication sharedApplication]openURL:tmpUrl];
}
else if(buttonIndex==){
NSString *title = [NSString stringWithFormat:@"%@可能是一个电话号码,你可以",linkMobile];
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:title delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"创建新联系人",@"添加到现有联系人", nil];
actionSheet.tag=;
[actionSheet showInView:self.view];
}
} else if (actionSheet.tag==){
if (buttonIndex==) {
if (iOS9Later) {
//1.创建Contact对象,须是可变
CNMutableContact *contact = [[CNMutableContact alloc] init];
//2.为contact赋值
[self setValueForContact:contact existContect:NO];
//3.创建新建联系人页面
_controller = [CNContactViewController viewControllerForNewContact:contact];
_controller.navigationItem.title = @"新建联系人";
//代理内容根据自己需要实现
_controller.delegate = self;
//4.跳转
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:_controller];
[self presentViewController:nc animated:YES completion:nil];
} else {
ABNewPersonViewController *picker = [[ABNewPersonViewController alloc] init];
ABRecordRef newPerson = ABPersonCreate();
ABMutableMultiValueRef multiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
CFErrorRef error = NULL; ABMultiValueAddValueAndLabel(multiValue, (__bridge CFTypeRef)(linkMobile), kABPersonPhoneMobileLabel, NULL);
ABRecordSetValue(newPerson, kABPersonPhoneProperty, multiValue , &error);
picker.displayedPerson = newPerson;
picker.newPersonViewDelegate = self;
picker.navigationItem.title = @"新建联系人";
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:picker];
[self presentViewController:nc animated:YES completion:nil];
CFRelease(newPerson);
CFRelease(multiValue);
}
} else if (buttonIndex==) {
if (iOS9Later) {
//1.跳转到联系人选择页面,注意这里没有使用UINavigationController
CNContactPickerViewController *controller = [[CNContactPickerViewController alloc] init];
controller.delegate = self;
[self presentViewController:controller animated:YES completion:nil];
} else {
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[self presentViewController:picker animated:YES completion:nil];
} }
}
}
#pragma mark - iOS9以前的ABNewPersonViewController代理方法
/* 该代理方法可dismiss新添联系人页面 */
-(void)newPersonViewController:(ABNewPersonViewController *)newPersonView didCompleteWithNewPerson:(ABRecordRef)person { [newPersonView dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - iOS9以前的ABPeoplePickerNavigationController的代理方法
-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person { [peoplePicker dismissViewControllerAnimated:YES completion:^{
/* 获取联系人电话 */
ABMutableMultiValueRef phoneMulti = ABRecordCopyValue(person, kABPersonPhoneProperty);
NSMutableArray *phones = [NSMutableArray array];
for (CFIndex i = ; i < ABMultiValueGetCount(phoneMulti); i++) {
NSString *aPhone = (__bridge_transfer NSString*)ABMultiValueCopyValueAtIndex(phoneMulti, i);
NSString *aLabel = (__bridge_transfer NSString*)ABMultiValueCopyLabelAtIndex(phoneMulti, i);
NSLog(@"手机号标签:%@ 手机号:%@",aLabel,aPhone);
[phones addObject:aPhone];
[phones addObject:aLabel];
}
ABNewPersonViewController *picker = [[ABNewPersonViewController alloc] init];
ABMutableMultiValueRef multiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
CFErrorRef error = NULL; ABMultiValueAddValueAndLabel(multiValue, (__bridge CFTypeRef)(linkMobile), kABPersonPhoneMobileLabel, NULL);
for (int i = ; i<[phones count]; i+=) { ABMultiValueAddValueAndLabel(multiValue, (__bridge CFTypeRef)([phones objectAtIndex:i]), (__bridge CFStringRef)([phones objectAtIndex:i+]), NULL);
}
ABRecordSetValue(person, kABPersonPhoneProperty, multiValue, &error);
picker.displayedPerson = person;
picker.newPersonViewDelegate = self;
picker.navigationItem.title = @"新建联系人";
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:picker];
[self presentViewController:nc animated:YES completion:nil];
CFRelease(multiValue);
CFRelease(phoneMulti);
}];
} #pragma mark - iOS9以后的CNContactViewControllerDelegate代理方法
/* 该代理方法可dismiss新添联系人页面 */
- (void)contactViewController:(CNContactViewController *)viewController didCompleteWithContact:(CNContact *)contact { [self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - iOS9以后的CNContactPickerDelegate的代理方法
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact{ [picker dismissViewControllerAnimated:YES completion:^{ //3.copy一份可写的Contact对象,不能用alloc
CNMutableContact *con = [contact mutableCopy];
//4.为contact赋值
[self setValueForContact:con existContect:YES];
//5.跳转到新建联系人页面
CNContactViewController *controller = [CNContactViewController viewControllerForNewContact:con];
controller.delegate = self;
controller.navigationItem.title = @"新建联系人";
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:controller];
[self presentViewController:nc animated:YES completion:nil];
}];
} /**
* 设置要保存的contact对象
*
* @param contact 联系人
* @param exist 是否需要重新创建
*/
- (void)setValueForContact:(CNMutableContact *)contact existContect:(BOOL)exist {
//电话
CNLabeledValue *phoneNumber = [CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberMobile value:[CNPhoneNumber phoneNumberWithStringValue:linkMobile]];
if (!exist) {
contact.phoneNumbers = @[phoneNumber];
} else {
//现有联系人情况
if ([contact.phoneNumbers count] >) {
NSMutableArray *phoneNumbers = [[NSMutableArray alloc] initWithArray:contact.phoneNumbers];
[phoneNumbers addObject:phoneNumber];
contact.phoneNumbers = phoneNumbers;
}else{
contact.phoneNumbers = @[phoneNumber];
}
}
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} @end
最后截图:

iOS开发学习-类似微信聊天消息中的电话号码点击保存到通讯录中的功能的更多相关文章
- IOS开发学习笔记043-QQ聊天界面实现
QQ聊天界面实现 效果如下: 实现过程: 1.首先实现基本界面 头像使用 UIImageView : 文字消息使用 UIButton 标签使用 UILable :水平居中 所有元素在一个cell中,在 ...
- IOS开发之——类似微信摇一摇的功能实现
首先,一直以为摇一摇的功能实现好高大上,结果百度了.我自己也模仿写了一个demo.主要代码如下: 新建一个项目,名字为AnimationShake. 主要代码: - (void)motionBegan ...
- 李洪强iOS开发之-环信04_消息
李洪强iOS开发之-环信04_消息 消息:IM 交互实体,在 SDK 中对应的类型是 EMMessage.EMMessage 由 EMMessageBody 组成. 构造消息 构造文字消息 EMT ...
- ios开发 学习积累20161027~20161031
前言 学习ios这几天来,总结下,函数的定义,调用.跟其他语言都有一定的区别: 几个特别重要的就是对象的迭代的使用和判断.取随机数.动画的实现及数组的深入研究等等 之前的总结地址 ios开发 学习积累 ...
- 类似微信聊天小程序-网易云信,IM DEMO小程序版本
类似微信聊天小程序-网易云信,IM DEMO小程序版本 代码地址: https://github.com/netease-im/NIM_Web_Weapp_Demo 云信IM DEMO 小程序版本 ( ...
- XMPPFrameWork IOS 开发(六)聊天室
原始地址:XMPPFrameWork IOS 开发(六)聊天室 聊天室 //初始化聊天室 XMPPJID *roomJID = [XMPPJID jidWithString:ROOM_JID]; xm ...
- MyEclipse项目中的文件点击右键Team选项中没有提交到SVN中的选项是怎么回事
MyEclipse项目中的文件点击右键Team选项中没有提交到SVN中的选项是怎么回事 其实你已经可以百度到很多方法: 例如下面博客提供的 http://www.xuebuyuan.com/95285 ...
- ios开发学习笔记(这里一定有你想要的东西,全部免费)
1,Search Bar 怎样去掉背景的颜色(storyboard里只能设置background颜色,可是发现clear Color无法使用). 其实在代码里还是可以设置的,那就是删除背景view [ ...
- iOS 即时通讯 + 仿微信聊天框架 + 源码
这些你造吗? 即时通讯(IM),在IOS这片江湖里面已经算是一个老者了,我这小旋风也是在很早以前巡山的时候,就知道有即时通讯这个妖怪,以前也多多少少接触过一些,在造APP的时候用过,哎呀,说着说着就感 ...
随机推荐
- .Net实现表达式计算(公式) 表达式字符串
文档原址:http://blog.csdn.net/fangxing80/article/details/5992661 实现复杂公式计算,比如含IF分支判断等,可考虑通过调用EXCEL公式获取值. ...
- 《Java 程序设计》课堂实践项目汇总链接
1.<Java 程序设计>课堂实践项目-命令行参数 2.<Java 程序设计>课堂实践项目-mini dc 3.<Java 程序设计>课堂实践项目-Arrays和S ...
- 【HNOI2014】画框
题面 题解 这又是一种套路啊233 将\(\sum a_i\)和\(\sum b_i\)分别看做\(x\)和\(y\),投射到平面直角坐标系中,于是就是找\(xy\)最小的点 于是可以先找出\(x\) ...
- cogs1885 [WC2006]水管局长数据加强版
BZOJ卡不过灰常蛋疼(毕竟人蠢自带巨大常数 这和动态维护最小生成树很像,但加边变成了删边,似乎没法做了. 然后根据之前的套路离线做,删边变成加边,就可以做了orz 二分查找的:(慢 // It is ...
- 异常 java.lang.NullPointerException at org.apache.jsp.index_jsp._jspService(index_jsp.java:124)
这是jsp报的异常 jsp代码: <% String LoginUsername = ""; String LoginPassword = ""; try ...
- python并发编程之多进程理论知识
一 什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行): egon在一个时间段内有很多任务要做:python备课的任务,写书的任 ...
- fiddler对安卓APP进行抓包
操作流程: 1.fiddler导出ca证书 操作路径: Tools -> Fiddler Options -> HTTPS -> Export Fiddler Root Certif ...
- 浅谈C与Java
Java的方法调用过程 Java变量:基本类型变量.指针变量 push 压入新的栈桢 在栈桢内部创建局部基本类型变量,接收参数值 在栈桢内部创建局部指针变量,接收参数值后,该指针变量指向堆上实例 po ...
- 木马分析出现python语言,360的安全人员不禁感叹还有这种操作?
几年前,敲诈者木马还是一个默默无闻的木马种类.然而,由于其极强的破坏力和直接且丰厚的财富回报,敲诈者木马这几年已经一跃成为曝光率最高的木马类型——甚至超越了盗号木马.远控木马.网购木马这传统三强.与此 ...
- shell小记
1.以#!/bin/bash 开头2.执行方式 bash sh ./ `script`3.变量: 系统变量 自定义变量 --->export 可导出为全局环境变量 set显示所 ...