iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如在应用中拨打电话,一些第三方软件会在应用内发送短信等。今天将和大家一起学习如何使用系统应用、使用系统服务完成上述功能。
事实上,我们在前面学习的内容中就有调用过系统内置的应用。比如我们在点击textView的超链接文本时,默认使用系统浏览器来访问连接,还有前面学习到地图服务,我们也可以通过打开系统内置的地图应用来完成地图服务。在开发某些应用时,如果希望能够调用iOS系统内置的电话、短信、邮件、浏览器应用,此时你可以直接使用UIApplication的OpenURL:方法指定特定的协议来打开不同的系统应用。常用的协议如下:
但是实际开发中我们发现,调用系统内置的应用来完成上述系统服务也存在着一些弊端:除了打电话之外,当你点击了发送短信(或邮件)操作之后直接启动了系统的短信(或邮件)应用程序,我们的应用其实此时已经处于一种挂起状态,打完电话或是发送完短信(或邮件)之后无法自动回到应用界面。而且不能在我们自己开发的应用中制定短信(或邮件)的内容。这显然不符合我们的需求,我们需要在应用程序内部完成这些操作。
拨打电话的功能实现相对简单,直接使用UIApplication的OpenURL:的方法并制定对应的协议就可以,打完电话后我们任然留在当前的应用界面。下面以一个简单的demo演示如何完成拨打电话的功能:
示例代码:
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
// 打电话 tel: 或tel:// 协议
- (IBAction)callPhone1:(id)sender {
// 使用这个协议会直接拨打电话
NSString *phoneNumber=@"10010";// 拨打的电话
NSString *url=[NSString stringWithFormat:@"tel://%@",phoneNumber];
[self openUrl:url];
}
// 打电话 telprompt:或telprompt:// 协议
- (IBAction)callPhone2:(id)sender {
// 这个协议在打电话前会先弹出一个对话框,提醒你是否打电话,然后在打完电话之后会回到程序中
NSString *phoneNumber=@"10010";// 拨打的电话
NSString *url=[NSString stringWithFormat:@"telprompt://%@",phoneNumber];
[self openUrl:url];
}
#pragma mark - 私有方法
-(void)openUrl:(NSString *)urlStr {
// 注意url中包含协议名称,iOS根据协议确定调用哪个应用,例如发送邮件是“tel://”其中“//”可以省略写成“tel:”(其他协议也是如此)
NSURL *url=[NSURL URLWithString:urlStr];
UIApplication *application=[UIApplication sharedApplication];
if(![application canOpenURL:url]){
NSLog(@"无法打开\"%@\",请确保此应用已经正确安装.",url);
return;
}
// 打开对应协议的应用
[[UIApplication sharedApplication] openURL:url];
}
@end
如果我们在应用中直接调用发送短信的系统应用,在完成发送任务后,我们停留在了系统应用当中,当然我们也可以在程序内部完成短信的编辑和发送任务。利用iOS中的MessageUI.framework,它提供了关于短信的UI接口供开发者在应用程序内部调用。从框架名称不难看出这是一套UI接口,提供有现成的短信的编辑界面,开发人员只需要通过编程的方式给短信控制器设置对应的参数即可。
在MessageUI.framework中用于发送短信的类是MFMessageComposeViewController。它继承于UINavigationController。下面介绍一下MFMessageComposeViewController使用步骤:
下面自定义一个发送短信的界面演示MFMessageComposeViewController的使用:我们可以定制短息控制器的相关参数,当我们弹出MFMessageComposeViewController的实例对象时,看到的就是短息的系统编辑界面,点击MFMessageComposeViewController 界面中的“发送”来完成短信发送工作,当然用户也可能点击“取消”按钮回到当前应用。当然,在我们完成发送任务之后还是可以回到当前应用的。
示例代码:
#import "ViewController.h"
#import
@interface ViewController ()<MFMessageComposeViewControllerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
// 发短信
- (IBAction)snedMessage1:(id)sender {
NSString *phoneNumber = @"10010";
NSString *urlString = [NSString stringWithFormat:@"sms://%@",phoneNumber];
NSURL *url = [NSURL URLWithString:urlString];
UIApplication *application = [UIApplication sharedApplication];
if(![application canOpenURL:url]){
NSLog(@"无法打开\"%@\",请确保此应用已经正确安装.",url);
return;
}
// 打开对应协议的应用
[[UIApplication sharedApplication] openURL:url];
}
- (IBAction)sendMessage2:(id)sender {
// 判断运营商是否能够发送文本
if(![MFMessageComposeViewController canSendText]) {
//显示提示框
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"提示信息" message:@"该设备不支持短信功能" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *alertAC = [UIAlertAction actionWithTitle:@"YES" style:UIAlertActionStyleCancel handler:nil];
[alertVC addAction:alertAC];
[self presentViewController:alertVC animated:YES completion:nil];
return;
}
// 1.初始化一个控制器MFMessageComposeViewController用来发送短信
MFMessageComposeViewController *messageVC = [[MFMessageComposeViewController alloc] init];
// 2.设置短信内容
// 收件人,可以设置多个
messageVC.recipients = @[@"10086",@"10010"];
// componentsSeparatedByString:根据某个字符将字符串分开成为不同的字符串,并存放到一个数组中。
// 短信内容
messageVC.body = @"恭喜发财,红包拿来";
// 判断运营商是否支持主题设置
if ([MFMessageComposeViewController canSendSubject]) {
NSLog(@"can send subject");
// 添加主题到消息控制器
messageVC.subject = @"我的主题";
}
// 判断硬件是否支持附件设置
if ([MFMessageComposeViewController canSendAttachments]) {
NSLog(@"can send attachments");
// 注意,不能直接给attachments赋值,系统将其看作只读性质对象
// messageVC.attachments = @[];
// 添加附件到消息控制器
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"attachment.png" ofType:nil];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
// 方法一:可以看到我们给文件的命名
[messageVC addAttachmentURL:fileURL withAlternateFilename:@"attachment"];
// 方法二:可以看到指定的文件类型,比如看到一个图片
/**
* attatchData:文件数据
* typeIdentifier:统一类型标识,标识具体文件类型,详情查看:帮助文档中System-Declared Uniform Type Identifiers
* fileName:展现给用户看的文件名称
*/
[messageVC addAttachmentData:[NSData dataWithContentsOfURL:fileURL] typeIdentifier:@"public.image" filename:@"attachment.png"];
/* 常用的类型标识
public.movie:Base type for movies (video with optional audio or other tracks).
public.audio:Base type for audio (no video).
public.image:Base type for images.
*/
}
// 3. 设置代理,通过代理监听短信的发送状态,并且释放短信控制器,
messageVC.messageComposeDelegate = self;//注意这里不是delegate而是messageComposeDelegate
// 4. 弹出消息布局控制器
[self presentViewController:messageVC animated:YES completion:nil];
// MessageUI.framework框架功能强大,除了可以支持发送短信给多人之外,自定义的消息可以为图片,并且消息支持HTML格式。最重要的是,如果彼此的手机都是iOS设备,并且都开通了iMessage功能,彼此之间的短信走的是网络通道,而不是走运营商通道!
}
#pragma mark MFMessageComposeViewControllerDelegate
// 发送完成,不管成功与否
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
switch (result) {
case MessageComposeResultCancelled:
NSLog(@"取消发送");
break;
case MessageComposeResultSent:
NSLog(@"发送成功");
break;
case MessageComposeResultFailed:
NSLog(@"发送失败");
break;
default:
break;
}
// 应该用下面的方法释放消息控制器,因为在面向对象程序开发中,有一个原则,谁申请,谁释放!
[self dismissViewControllerAnimated:YES completion:nil];
// 当然,此方法也可以正常工作,因为系统会将关闭消息发送给self
// [controller dismissViewControllerAnimated:YES completion:nil];
}
@end
这里需要强调一下:
那么,熟悉了MFMessageComposeViewController之后,我们来看一下如何在应用中发送邮件。 邮件的发送实现起来和短信功能相类似,是由MessageUI.framework的另外一个类MFMailComposeViewController 来实现的。MFMailComposeViewController用法和步骤和MFMessageComposeViewController完全一致,只是功能不同。下面看一下MFMailComposeViewController的使用:
示例代码:
#import "ViewController.h"
#import
@interface ViewController ()<MFMailComposeViewControllerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
// 发邮件 mailto: 或 mailto:// 协议
- (IBAction)sendEmail1:(id)sender {
NSString *mailAddress = @"[email protected]";
NSString *urlStr = [NSString stringWithFormat:@"mailto://%@",mailAddress];
NSURL *url = [NSURL URLWithString:urlStr];
UIApplication *application = [UIApplication sharedApplication];
if(![application canOpenURL:url]){
NSLog(@"无法打开\"%@\",请确保此应用已经正确安装.",url);
return;
}
// 打开对应协议的应用
[[UIApplication sharedApplication] openURL:url];
}
- (IBAction)sendEmail2:(id)sender {
// 判断用户设备是否能够发送邮件
if(![MFMailComposeViewController canSendMail]) {
//显示提示框
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"提示信息" message:@"提醒用户设置邮箱" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *alertAC = [UIAlertAction actionWithTitle:@"YES" style:UIAlertActionStyleCancel handler:nil];
[alertVC addAction:alertAC];
[self presentViewController:alertVC animated:YES completion:nil];
return;
}
// 1.初始化化一个邮件控制器MFMailComposeViewController用来编辑和发送邮件
MFMailComposeViewController *mailVC = [[MFMailComposeViewController alloc] init];
// 设置代理
mailVC.mailComposeDelegate = self;
// 2.设置邮件内容
// 收件人,可以设置多个
[mailVC setToRecipients:@[@"[email protected]"]];
// 抄送人
[mailVC setCcRecipients:@[@"[email protected]"]];
// 密送人
[mailVC setBccRecipients:@[@"[email protected]"]];
// 邮件主题
[mailVC setSubject:@"我的工作日报"];
// 邮件正文
[mailVC setMessageBody:@"这是我的工作报告,请审阅!
P.S. 我的头像牛X吗?" isHTML:YES];
// 附件
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"头像.png" ofType:nil];
NSData *data = [NSData dataWithContentsOfFile:filePath];
[mailVC addAttachmentData:data mimeType:@"image/png" fileName:@"头像.png"];//第二个参数是mimeType类型,jpg图片对应image/jpeg
// 3. 弹出邮件控制器
[self presentViewController:mailVC animated:YES completion:nil];
}
#pragma mark MFMailComposeViewControllerDelegate
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result) {
case MFMailComposeResultSent:
NSLog(@"发送成功.");
break;
case MFMailComposeResultSaved://如果存储为草稿(点取消会提示是否存储为草稿,存储后可以到系统邮件应用的对应草稿箱找到)
NSLog(@"邮件已保存.");
break;
case MFMailComposeResultCancelled:
NSLog(@"取消发送.");
break;
default:
NSLog(@"发送失败.");
break;
}
if (error) {
NSLog(@"发送邮件过程中发生错误,错误信息:%@",error.localizedDescription);
}
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
网页的浏览相对比较简单,我们使用application的openURL:方法打开一个合法连接就可以直接进入系统的内置浏览器,在应用内部浏览可以使用UIWebView加载网络请求,UIWebView的使用前文中也有介绍,在这里就不多做赘述了。
示例代码:
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
// 调用浏览器
- (IBAction)browser1:(id)sender {
NSString *urlStr = @"http://www.baidu.com";
NSURL *url = [NSURL URLWithString:urlStr];
UIApplication *application = [UIApplication sharedApplication];
if(![application canOpenURL:url]){
NSLog(@"无法打开\"%@\",请确保此应用已经正确安装.",url);
return;
}
// 打开对应协议的应用
[[UIApplication sharedApplication] openURL:url];
}
- (IBAction)browser2:(id)sender {
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
[self.view addSubview:webView];
}
@end
从上面的几个示例中不难发现当openURL:方法只要指定一个URL Schame并且已经安装了对应的应用程序就可以打开此应用。当然,如果是自己开发的应用也可以调用openURL方法来打开。假设你现在开发了一个应用A,如果用户机器上已经安装了此应用,并且在应用B中希望能够直接打开A。那么首先需要确保应用A已经配置了Url Types,具体方法就是在plist文件中添加URL types节点并配置URL Schemas作为具体协议,配置URL identifier作为这个URL的唯一标识,如下图:
然后就可以调用openURL方法像打开系统应用一样打开第三方应用程序了:
// 打开第三方应用
- (IBAction)thirdPartyApplicationClick:(UIButton *)sender {
NSString *urlStr = @"thirdParty://myparams";
NSURL *url = [NSURL URLWithString:urlStr];
// 打开对应协议的应用
[[UIApplication sharedApplication] openURL:url];
}
注意:
就像调用系统应用一样,协议后面可以传递一些参数,这样一来在应用中可以在AppDelegate的
- (BOOL)application:(UIApplication )app openURL:(NSURL )url options:(NSDictionary
/** @pramas 当用户通过其它应用启动本应用时,会回调这个方法
*
* prams: url //其它应用调用openURL:方法时传过来的
* app //打开本应用的应用程序
* options // 应用的配置参数
*
* return: bool // 是否允许打开本程序
*/
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options {
NSLog(@"url:%@,source application:%@,params:%@",url,app,[url host]);
return YES;// 是否打开
}
下面是常用APP的Url Scheme 前缀
QQ mqq://
微信是 weixin://
网易新闻 newsapp://
淘宝 taobao://
点评 dianping:// dianping://search
微博 sinaweibo://
weico微博 weico://
支付宝 alipay://
豆瓣fm: doubanradio://
微盘 sinavdisk://
网易公开课 ntesopen://
美团 imeituan://
人人 renren://
我查查 wcc://
1号店 wccbyihaodian://
有道词典 yddictproapp://
知乎 zhihu://
优酷 youku://
ZAKER zakeripad://
京东hd openApp.jdiPad://
易迅 icson://;yixunipad://
wunderlist wunderlist://
支付宝 alipay://
查找朋友 grenada://;findmyfriends://;fmf1://
查找iphone fmip1://
触宝拨号:dialer://
蜂窝网络:prefs:root=MOBILE_DATA_SETTINGS_ID
WIFI:prefs:root=WIFI(WIFI这几个字母一定要大写)
定位服务:prefs:root=LOCATION_SERVICES
备忘录:mobilenotes://
高德地图:iosamap://
今日头条 snssdk141://
挖财记账 wacai://
QQ音乐 :QQmusic://
酷我音乐 com.kuwo.kwmusic.kwmusicForKwsing://
酷狗音乐 kugouURL://
京东 openApp.jdMobile://
QQ音乐 qqmusic://
QQ斗地主 tencent382://
QQ浏览器 mttbrowser://
QQ安全中心 qmtoken://
QQ国际版 mqqiapi://
搜狗输入法 com.sogou.sogouinput://
搜狐视频 sohuvideo-iphone:// 或 sohuvideo://
搜狐新闻 sohunews://
设置 prefs:root=SETTING
定位服务 prefs:root=LOCATION_SERVICES
E-Mail MESSAGE://
ifttt ifttt://
名片全能王hd camcard://;CamCardHDOpenAPI://
拉手团购hd LaShouGroupHDPay://
美团hd iMeituan://
evermemo evermemo://
网易云课堂 wangyiyunketang://
网易公开课 ntesopen://
订票助手2 trainassistfree://
pcalc lite pcalc://
爱奇艺视频 QIYIHD-iPad://
三国kill sgk://
TuneIn Radio tunein:// 或 tuneinpro://
OfficeSuite mobisystemsofficesuite://
WPS Office KingsoftOfficeApp://
Line line://
1Password onepassword://
mdict mdict://
名片全能王camcard://
支付宝alipay://
豆瓣fm:doubanradio://
微盘 sinavdisk://
网易公开课ntesopen://
我查查 wcc://
1号店wccbyihaodian://
有道词典yddictproapp://
知乎zhihu://
墨客 com.moke.moke-1://
名片全能王 camcard://
扫描全能王 camscanner://
12306订票助手 trainassist://
金山词霸 com.kingsoft.powerword.6://
节奏大师 tencentrm://
凤凰新闻 comIfeng3GifengNews://
高铁管家 gtgj://
飞信 fetion://
豆瓣FM doubanradio://
大智慧 dzhiphone://
布卡漫画 buka://
爱奇艺PPS ppstream://
哔哩哔哩动画 bilibili://
56视频 com.56Video://
365日历 rili365://
58同城 wbmain://
遇见 iaround://
陌陌 momochat://
旺旺卖家版 wangwangseller://
蜻蜓FM qtfmp://
浦发银行 wx1cb534bb13ba3dbd://
招商银行 cmbmobilebank://
支付宝 alipay://
建设银行 wx2654d9155d70a468://
工商银行 com.icbc.iphoneclient://
随手记 FDMoney://
腾讯企业邮箱 qqbizmailDistribute2://
腾讯手机管家 mqqsecure://
腾讯视频 tenvideo:// 或 tenvideo2:// 或 tenvideo3://
腾讯微博 TencentWeibo://
天猫 tmall://
天天星连萌 tencent100689806://
天天爱消除 tencent100689805://
天天酷跑 tencent100692648://
天天飞车 tencent100695850://
天天动听 ttpod://扇贝新闻 shanbaynews://
扇贝单词 shanbay://
扇贝单词hd shanbaywordshd://
skype skype://
搜狐视频hd sohu-SViPad://;sohuvideohd://
teamviewer:teamviewer8://
格志 griddiary://;sumi-interactive://
淘宝hd taobao://;itaobao://;taobaohd://
天猫 tmall://
腾讯视频hd tenvideohd://;tenvideo2://
同步推正版HD tbtui://;tuihd://
航旅纵横pro umetrippro://
mathpad myscriptmathpad://
雅虎天气! yweather://
一号店 ipadstore://
优酷hd youkuhd://
知乎 zhihu://
欧陆词典pro eudic://
拓词 towordsp://
Clear(著名的Todo应用) clearapp://
电话 mobilephone://
猎豹浏览器:sinaweibosso.422729959://
UC浏览器:ucbrowser://
支付宝:alipay://
新浪微博:weibo://
优酷:youku://
节奏大师:节奏大师tencentrm://
刀塔传奇:刀塔传奇teiron2273://
天天动听:ttpod://
淘宝taobao://有道词典 yddict://
掌阅iReader iReader://
艺龙旅行 elongIPhone://
迅雷+迅雷云播 thunder://
熊猫公交 wb1405365637://
携程无线 CtripWireless://
无线苏州 SuZhouTV://
唯品会 vipshop://
微视 weishiiosscheme://
微拍 wpweipai://
旺信 wangxin://
网易公开课 ntesopen://
网易将军令 netease-mkey://
万年历 youloft.419805549://
土豆视频 tudou://
同花顺 amihexin://
天涯社区 tianya://
天气通Pro sinaweatherpro://
天气通 sinaweather://
墨迹天气 rm434209233MojiWeather://
腾讯新闻 qqnews://
腾讯微云 weiyun://
腾讯地图 sosomap://
淘宝旅行 taobaotravel://
人人 renrenios://PPTV pptv://
爱奇艺视频 qiyi-iphone://
暴风影音 com.baofeng.play://
保卫萝卜2 wb2217954495://
保卫萝卜 wb1308702128://
百度云 baiduyun://
百度音乐 baidumusic://
百度视频 baiduvideoiphone:// 或 bdviphapp://
百度糯米 bainuo://
百度魔图 photowonder://
百度魔拍 wondercamera://
百度地图 baidumap://
百度导航 bdNavi://
百度视频hd BaiduVideoiPad://;baiduvideoipadapp://
百度相册hd BaiDuCloudAlbumHD://
百度浏览器hd bdbrowser://
百度文库hd bdwenku://
威锋网 com.weiphone.forum://
新浪微博 weibo:// 或 sinaweibo://
网易邮箱 neteasemail://
百度输入法 BaiduIMShop://
C浏览器 ucbrowser://
一个one clover-one://
当当hd dangdanghd://;ddhd://
大众点评hd dianpinghd://
多看阅读 duokan-reader://
艺龙旅行hd elongiPad://
圈点hd skitch://
印象笔记hd enx://
备忘录 mobilenotes://
qq通讯录 tencentappqqpim://
Chrome谷歌浏览器 googlechrome://
Calendars 5 calendars://
PDF Expert 5 pdfexpert5presence://
Documents 5 rdocs://
nPlayer nplayer-http://
GPlayer gplayer://
AVPlayer HD AVPlayerHD://
AVPlayer AVPlayer://
Ace Player aceplayer://