–系统应用与系统服务
iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录、微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等。今天将和大家一起学习如何使用系统应用、使用系统服务:
系统应用
在开发某些应用时可能希望能够调用iOS系统内置的电话、短信、邮件、浏览器应用,此时你可以直接使用UIApplication的OpenURL:方法指定特定的协议来打开不同的系统应用。常用的协议如下:
打电话:tel:或者tel://、telprompt:或telprompt://(拨打电话前有提示)
发短信:sms:或者sms://
发送邮件:mailto:或者mailto://
启动浏览器:http:或者http://
下面以一个简单的demo演示如何调用上面几种系统应用:
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 |
// // ViewController.m // iOSSystemApplication // // Created by Kenshin Cui on 14/04/05. // Copyright (c) 2014年 cmjstudio. All rights reserved. // #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } #pragma mark - UI事件 //打电话 - (IBAction)callClicK:(UIButton *)sender { NSString *phoneNumber=@"18500138888"; // NSString *url=[NSString stringWithFormat:@"tel://%@",phoneNumber];//这种方式会直接拨打电话 NSString *url=[NSString stringWithFormat:@"telprompt://%@",phoneNumber];//这种方式会提示用户确认是否拨打电话 [self openUrl:url]; } //发送短信 - (IBAction)sendMessageClick:(UIButton *)sender { NSString *phoneNumber=@"18500138888"; NSString *url=[NSString stringWithFormat:@"sms://%@",phoneNumber]; [self openUrl:url]; } //发送邮件 - (IBAction)sendEmailClick:(UIButton *)sender { NSString *mailAddress=@"kenshin@hotmail.com"; NSString *url=[NSString stringWithFormat:@"mailto://%@",mailAddress]; [self openUrl:url]; } //浏览网页 - (IBAction)browserClick:(UIButton *)sender { NSString *url=@"http://www.cnblogs.com/kenshincui"; [self openUrl:url]; } #pragma mark - 私有方法 -(void)openUrl:(NSString *)urlStr{ //注意url中包含协议名称,iOS根据协议确定调用哪个应用,例如发送邮件是“sms://”其中“//”可以省略写成“sms:”(其他协议也是如此) NSURL *url=[NSURL URLWithString:urlStr]; UIApplication *application=[UIApplication sharedApplication]; if(![application canOpenURL:url]){ NSLog(@"无法打开"%@",请确保此应用已经正确安装.",url); return; } [[UIApplication sharedApplication] openURL:url]; } @end<br> |
不难发现当openURL:方法只要指定一个URL Schame并且已经安装了对应的应用程序就可以打开此应用。当然,如果是自己开发的应用也可以调用openURL方法来打开。假设你现在开发了一个应用A,如果用户机器上已经安装了此应用,并且在应用B中希望能够直接打开A。那么首先需要确保应用A已经配置了Url Types,具体方法就是在plist文件中添加URL types节点并配置URL Schemas作为具体协议,配置URL identifier作为这个URL的唯一标识,如下图:
然后就可以调用openURL方法像打开系统应用一样打开第三方应用程序了:
1 2 3 4 5 |
//打开第三方应用 - (IBAction)thirdPartyApplicationClick:(UIButton *)sender { NSString *url=@"cmj://myparams"; [self openUrl:url]; } |
就像调用系统应用一样,协议后面可以传递一些参数(例如上面传递的myparams),这样一来在应用中可以在AppDelegate的-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation代理方法中接收参数并解析。
1 2 3 4 5 |
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{ NSString *str=[NSString stringWithFormat:@"url:%@,source application:%@,params:%@",url,sourceApplication,[url host]]; NSLog(@"%@",str); return YES;//是否打开 } |
系统服务
短信与邮件
调用系统内置的应用来发送短信、邮件相当简单,但是这么操作也存在着一些弊端:当你点击了发送短信(或邮件)操作之后直接启动了系统的短信(或邮件)应用程序,我们的应用其实此时已经处于一种挂起状态,发送完(短信或邮件)之后无法自动回到应用界面。如果想要在应用程序内部完成这些操作则可以利用iOS中的MessageUI.framework,它提供了关于短信和邮件的UI接口供开发者在应用程序内部调用。从框架名称不难看出这是一套UI接口,提供有现成的短信和邮件的编辑界面,开发人员只需要通过编程的方式给短信和邮件控制器设置对应的参数即可。
在MessageUI.framework中主要有两个控制器类分别用于发送短信(MFMessageComposeViewController)和邮件(MFMailComposeViewController),它们均继承于UINavigationController。由于两个类使用方法十分类似,这里主要介绍一下MFMessageComposeViewController使用步骤:
- 创建MFMessageComposeViewController对象。
- 设置收件人recipients、信息正文body,如果运行商支持主题和附件的话可以设置主题subject、附件attachments(可以通过canSendSubject、canSendAttachments方法判断是否支持)
- 设置代理messageComposeDelegate(注意这里不是delegate属性,因为delegate属性已经留给UINavigationController,MFMessageComposeViewController没有覆盖此属性而是重新定义了一个代理),实现代理方法获得发送状态。
下面自定义一个发送短信的界面演示MFMessageComposeViewController的使用:
用户通过在此界面输入短信信息点击“发送信息”调用MFMessageComposeViewController界面来展示或进一步编辑信息,点击MFMessageComposeViewController中的“发送”来完成短信发送工作,当然用户也可能点击“取消”按钮回到前一个短信编辑页面。
实现代码:
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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
// // KCSendMessageViewController.m // iOSSystemApplication // // Created by Kenshin Cui on 14/04/05. // Copyright (c) 2014年 cmjstudio. All rights reserved. // #import "KCSendMessageViewController.h" #import <MessageUI/MessageUI.h> @interface KCSendMessageViewController ()<MFMessageComposeViewControllerDelegate> @property (weak, nonatomic) IBOutlet UITextField *receivers; @property (weak, nonatomic) IBOutlet UITextField *body; @property (weak, nonatomic) IBOutlet UITextField *subject; @property (weak, nonatomic) IBOutlet UITextField *attachments; @end @implementation KCSendMessageViewController #pragma mark - 控制器视图方法 - (void)viewDidLoad { [super viewDidLoad]; } #pragma mark - UI事件 - (IBAction)sendMessageClick:(UIButton *)sender { //如果能发送文本信息 if([MFMessageComposeViewController canSendText]){ MFMessageComposeViewController *messageController=[[MFMessageComposeViewController alloc]init]; //收件人 messageController.recipients=[self.receivers.text componentsSeparatedByString:@","]; //信息正文 messageController.body=self.body.text; //设置代理,注意这里不是delegate而是messageComposeDelegate messageController.messageComposeDelegate=self; //如果运行商支持主题 if([MFMessageComposeViewController canSendSubject]){ messageController.subject=self.subject.text; } //如果运行商支持附件 if ([MFMessageComposeViewController canSendAttachments]) { /*第一种方法*/ //messageController.attachments=...; /*第二种方法*/ NSArray *attachments= [self.attachments.text componentsSeparatedByString:@","]; if (attachments.count>0) { [attachments enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NSString *path=[[NSBundle mainBundle]pathForResource:obj |