系统应用于系统服务

系统应用

在开发某些应用时可能希望能够调用iOS系统内置的电话、短信、邮件、浏览器应用,此时你可以直接使用UIApplication的OpenURL:方法指定特定的协议来打开不同的系统应用。常用的协议如下:

打电话:tel:或者tel://、telprompt:或telprompt://(拨打电话前有提示)

发短信:sms:或者sms://

发送邮件:mailto:或者mailto://

启动浏览器:http:或者http://

 
 1 下面以一个简单的demo演示如何调用上面几种系统应用:
2 //
3 // ViewController.m
4 // iOSSystemApplication
5 //
6 // Created by Kenshin Cui on 14/04/05.
7 // Copyright (c) 2014年 cmjstudio. All rights reserved.
8 //
9 #import "ViewController.h"
10 @interface ViewController ()
11 @end
12 @implementation ViewController
13 - (void)viewDidLoad {
14 [super viewDidLoad];
15 }
16 #pragma mark - UI事件
17 //打电话
18 - (IBAction)callClicK:(UIButton *)sender {
19 NSString *phoneNumber=@"18500138888";
20 // NSString *url=[NSString stringWithFormat:@"tel://%@",phoneNumber];//这种方式会直接拨打电话
21 NSString *url=[NSString stringWithFormat:@"telprompt://%@",phoneNumber];//这种方式会提示用户确认是否拨打电话
22 [self openUrl:url];
23 }
24 //发送短信
25 - (IBAction)sendMessageClick:(UIButton *)sender {
26 NSString *phoneNumber=@"18500138888";
27 NSString *url=[NSString stringWithFormat:@"sms://%@",phoneNumber];
28 [self openUrl:url];
29 }
30 //发送邮件
31 - (IBAction)sendEmailClick:(UIButton *)sender {
32 NSString *mailAddress=@"kenshin@hotmail.com";
33 NSString *url=[NSString stringWithFormat:@"mailto://%@",mailAddress];
34 [self openUrl:url];
35 }
36 //浏览网页
37 - (IBAction)browserClick:(UIButton *)sender {
38 NSString *url=@"http://www.cnblogs.com/kenshincui";
39 [self openUrl:url];
40 }
41 #pragma mark - 私有方法
42 -(void)openUrl:(NSString *)urlStr{
43 //注意url中包含协议名称,iOS根据协议确定调用哪个应用,例如发送邮件是“sms://”其中“//”可以省略写成“sms:”(其他协议也是如此)
44 NSURL *url=[NSURL URLWithString:urlStr];
45 UIApplication *application=[UIApplication sharedApplication];
46 if(![application canOpenURL:url]){
47 NSLog(@"无法打开\"%@\",请确保此应用已经正确安装.",url);
48 return;
49 }
50 [[UIApplication sharedApplication] openURL:url];
51 }
52 @end

不 难发现当openURL:方法只要指定一个URL Schame并且已经安装了对应的应用程序就可以打开此应用。当然,如果是自己开发的应用也可以调用openURL方法来打开。假设你现在开发了一个应用 A,如果用户机器上已经安装了此应用,并且在应用B中希望能够直接打开A。那么首先需要确保应用A已经配置了Url Types,具体方法就是在plist文件中添加URL types节点并配置URL Schemas作为具体协议,配置URL identifier作为这个URL的唯一标识,如下图:

然后就可以调用openURL方法像打开系统应用一样打开第三方应用程序了:

 
1 //打开第三方应用
2 - (IBAction)thirdPartyApplicationClick:(UIButton *)sender {
3 NSString *url=@"cmj://myparams";
4 [self openUrl:url];
5 }

就 像调用系统应用一样,协议后面可以传递一些参数(例如上面传递的myparams),这样一来在应用中可以在AppDelegate的 -(BOOL)application:(UIApplication *)application openURL:(NSURL *)url

 
1 sourceApplication:(NSString *)sourceApplication annotation:(id)annotation代理方法中接收参数并解析。
2 -(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
3 NSString *str=[NSString stringWithFormat:@"url:%@,source application:%@,params:%@",url,sourceApplication,[url host]];
4 NSLog(@"%@",str);
5 return YES;//是否打开
6 }

系统服务

短信与邮件

调 用系统内置的应用来发送短信、邮件相当简单,但是这么操作也存在着一些弊端:当你点击了发送短信(或邮件)操作之后直接启动了系统的短信(或邮件)应用程 序,我们的应用其实此时已经处于一种挂起状态,发送完(短信或邮件)之后无法自动回到应用界面。如果想要在应用程序内部完成这些操作则可以利用iOS中的 MessageUI.framework,它提供了关于短信和邮件的UI接口供开发者在应用程序内部调用。从框架名称不难看出这是一套UI接口,提供有现 成的短信和邮件的编辑界面,开发人员只需要通过编程的方式给短信和邮件控制器设置对应的参数即可。

在 MessageUI.framework中主要有两个控制器类分别用于发送短信(MFMessageComposeViewController)和邮件 (MFMailComposeViewController),它们均继承于UINavigationController。由于两个类使用方法十分类 似,这里主要介绍一下MFMessageComposeViewController使用步骤:

  1. 创建MFMessageComposeViewController对象。

  2. 设置收件人recipients、信息正文body,如果运行商支持主题和附件的话可以设置主题subject、附件attachments(可以通过canSendSubject、canSendAttachments方法判断是否支持)

  3. 设 置代理messageComposeDelegate(注意这里不是delegate属性,因为delegate属性已经留给 UINavigationController,MFMessageComposeViewController没有覆盖此属性而是重新定义了一个代 理),实现代理方法获得发送状态。

下面自定义一个发送短信的界面演示MFMessageComposeViewController的使用:

用 户通过在此界面输入短信信息点击“发送信息”调用MFMessageComposeViewController界面来展示或进一步编辑信息,点击 MFMessageComposeViewController中的“发送”来完成短信发送工作,当然用户也可能点击“取消”按钮回到前一个短信编辑页 面。

实现代码:

 
 1 //
2 // KCSendMessageViewController.m
3 // iOSSystemApplication
4 //
5 // Created by Kenshin Cui on 14/04/05.
6 // Copyright (c) 2014年 cmjstudio. All rights reserved.
7 //
8 #import "KCSendMessageViewController.h"
9 #import
10 @interface KCSendMessageViewController ()
11 @property (weak, nonatomic) IBOutlet UITextField *receivers;
12 @property (weak, nonatomic) IBOutlet UITextField *body;
13 @property (weak, nonatomic) IBOutlet UITextField *subject;
14 @property (weak, nonatomic) IBOutlet UITextField *attachments;
15 @end
16 @implementation KCSendMessageViewController
17 #pragma mark - 控制器视图方法
18 - (void)viewDidLoad {
19 [super viewDidLoad];
20
21 }
22 #pragma mark - UI事件
23 - (IBAction)sendMessageClick:(UIButton *)sender {
24 //如果能发送文本信息
25 if([MFMessageComposeViewController canSendText]){
26 MFMessageComposeViewController *messageController=[[MFMessageComposeViewController alloc]init];
27 //收件人
28 messageController.recipients=[self.receivers.text componentsSeparatedByString:@","];
29 //信息正文
30 messageController.body=self.body.text;
31 //设置代理,注意这里不是delegate而是messageComposeDelegate
32 messageController.messageComposeDelegate=self;
33 //如果运行商支持主题
34 if([MFMessageComposeViewController canSendSubject]){
35 messageController.subject=self.subject.text;
36 }
37 //如果运行商支持附件
38 if ([MFMessageComposeViewController canSendAttachments]) {
39 /*第一种方法*/
40 //messageController.attachments=...;
41
42 /*第二种方法*/
43 NSArray *attachments= [self.attachments.text componentsSeparatedByString:@","];
44 if (attachments.count>0) {
45 [attachments enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
46 NSString *path=[[NSBundle mainBundle]pathForResource:obj ofType:nil];
47 NSURL *url=[NSURL fileURLWithPath:path];
48 [messageController addAttachmentURL:url withAlternateFilename:obj];
49 }];
50 }
51
52 /*第三种方法*/
53 // NSString *path=[[NSBundle mainBundle]pathForResource:@"photo.jpg" ofType:nil];
54 // NSURL *url=[NSURL fileURLWithPath:path];
55 // NSData *data=[NSData dataWithContentsOfURL:url];
56 /**
57 * attatchData:文件数据
58 * uti:统一类型标识,标识具体文件类型,详情查看:帮助文档中System-Declared Uniform Type Identifiers
59 * fileName:展现给用户看的文件名称
60 */
61 // [messageController addAttachmentData:data typeIdentifier:@"public.image" filename:@"photo.jpg"];
62 }
63 [self presentViewController:messageController animated:YES completion:nil];
64 }
65 }
66 #pragma mark - MFMessageComposeViewController代理方法
67 //发送完成,不管成功与否
68 -(void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result{
69 switch (result) {
70 case MessageComposeResultSent:
71 NSLog(@"发送成功.");
72 break;
73 case MessageComposeResultCancelled:
74 NSLog(@"取消发送.");
75 break;
76 default:
77 NSLog(@"发送失败.");
78 break;
79 }
80 [self dismissViewControllerAnimated:YES completion:nil];
81 }
82 @end

这里需要强调一下:

  • MFMessageComposeViewController的代理不是通过delegate属性指定的而是通过messageComposeDelegate指定的。

  • 可以通过几种方式来指定发送的附件,在这个过程中请务必指定文件的后缀,否则在发送后无法正确识别文件类别(例如如果发送的是一张jpg图片,在发送后无法正确查看图片)。

  • 无 论发送成功与否代理方法-(void)messageComposeViewController: (MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result都会执行,通过代理参数中的result来获得发送 状态。

其实只要熟悉了MFMessageComposeViewController之后,那么用于发送邮件的 MFMailComposeViewController用法和步骤完全一致,只是功能不同。下面看一下 MFMailComposeViewController的使用:

 
 1 //
2 // KCSendEmailViewController.m
3 // iOSSystemApplication
4 //
5 // Created by Kenshin Cui on 14/04/05.
6 // Copyright (c) 2014年 cmjstudio. All rights reserved.
7 //
8 #import "KCSendEmailViewController.h"
9 #import
10 @interface KCSendEmailViewController ()
11 @property (weak, nonatomic) IBOutlet UITextField *toTecipients;//收件人
12 @property (weak, nonatomic) IBOutlet UITextField *ccRecipients;//抄送人
13 @property (weak, nonatomic) IBOutlet UITextField *bccRecipients;//密送人
14 @property (weak, nonatomic) IBOutlet UITextField *subject; //主题
15 @property (weak, nonatomic) IBOutlet UITextField *body;//正文
16 @property (weak, nonatomic) IBOutlet UITextField *attachments;//附件
17 @end
18 @implementation KCSendEmailViewController
19 - (void)viewDidLoad {
20 [super viewDidLoad];
21 }
22 #pragma mark - UI事件
23 - (IBAction)sendEmailClick:(UIButton *)sender {
24 //判断当前是否能够发送邮件
25 if ([MFMailComposeViewController canSendMail]) {
26 MFMailComposeViewController *mailController=[[MFMailComposeViewController alloc]init];
27 //设置代理,注意这里不是delegate,而是mailComposeDelegate
28 mailController.mailComposeDelegate=self;
29 //设置收件人
30 [mailController setToRecipients:[self.toTecipients.text componentsSeparatedByString:@","]];
31 //设置抄送人
32 if (self.ccRecipients.text.length>0) {
33 [mailController setCcRecipients:[self.ccRecipients.text componentsSeparatedByString:@","]];
34 }
35 //设置密送人
36 if (self.bccRecipients.text.length>0) {
37 [mailController setBccRecipients:[self.bccRecipients.text componentsSeparatedByString:@","]];
38 }
39 //设置主题
40 [mailController setSubject:self.subject.text];
41 //设置内容
42 [mailController setMessageBody:self.body.text isHTML:YES];
43 //添加附件
44 if (self.attachments.text.length>0) {
45 NSArray *attachments=[self.attachments.text componentsSeparatedByString:@","] ;
46 [attachments enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
47 NSString *file=[[NSBundle mainBundle] pathForResource:obj ofType:nil];
48 NSData *data=[NSData dataWithContentsOfFile:file];
49 [mailController addAttachmentData:data mimeType:@"image/jpeg" fileName:obj];//第二个参数是mimeType类型,jpg图片对应image/jpeg
50 }];
51 }
52 [self presentViewController:mailController animated:YES completion:nil];
53
54 }
55 }
56 #pragma mark - MFMailComposeViewController代理方法
57 -(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error{
58 switch (result) {
59 case MFMailComposeResultSent:
60 NSLog(@"发送成功.");
61 break;
62 case MFMailComposeResultSaved://如果存储为草稿(点取消会提示是否存储为草稿,存储后可以到系统邮件应用的对应草稿箱找到)
63 NSLog(@"邮件已保存.");
64 break;
65 case MFMailComposeResultCancelled:
66 NSLog(@"取消发送.");
67 break;
68
69 default:
70 NSLog(@"发送失败.");
71 break;
72 }
73 if (error) {
74 NSLog(@"发送邮件过程中发生错误,错误信息:%@",error.localizedDescription);
75 }
76 [self dismissViewControllerAnimated:YES completion:nil];
77 }
78 @end

运行效果:

iOS开发——高级技术&系统应用于系统服务的更多相关文章

  1. iOS开发——高级技术OC篇&运行时(Runtime)机制

    运行时(Runtime)机制 本文将会以笔者个人的小小研究为例总结一下关于iOS开发中运行时的使用和常用方法的介绍,关于跟多运行时相关技术请查看笔者之前写的运行时高级用法及相关语法或者查看响应官方文档 ...

  2. iOS开发——高级技术精选OC篇&Runtime之字典转模型实战

    Runtime之字典转模型实战 如果您还不知道什么是runtime,那么请先看看这几篇文章: http://www.cnblogs.com/iCocos/p/4734687.html http://w ...

  3. iOS开发——高级技术&签名机制

    签名机制 最近看了objc.io上第17期中的文章 <Inside Code Signing> 对应的中文翻译版 <代码签名探析> ,受益颇深,对iOS代码签名机制有了进一步的 ...

  4. iOS开发——高级技术&广告服务

    广告服务 上 面也提到做iOS开发另一收益来源就是广告,在iOS上有很多广告服务可以集成,使用比较多的就是苹果的iAd.谷歌的Admob,下面简单演示一下如何 使用iAd来集成广告.使用iAd集成广告 ...

  5. iOS开发——高级技术&内购服务

    内购服务 大家都知道做iOS开发本身的收入有三种来源:出售应用.内购和广告.国内用户通常很少直接 购买应用,因此对于开发者而言(特别是个人开发者),内购和广告收入就成了主要的收入来源.内购营销模式,通 ...

  6. iOS开发——高级技术&摇一摇功能的实现

    摇一摇功能的实现 在AppStore中多样化功能越来越多的被使用了,所以今天就开始介绍一些iOS开发的比较实用,但是我们接触的比较少的功能,我们先从摇一摇功能开始 在 UIResponder中存在这么 ...

  7. iOS开发——高级技术&PassBook服务

    PassBook服务 Passbook是苹果推出的一个管理登机牌.会员卡.电影票.优惠券等信息的 工具.Passbook就像一个卡包,用于存放你的购物卡.积分卡.电影票.礼品卡等,而这些票据就是一个“ ...

  8. iOS开发——高级技术&蓝牙服务

    蓝牙服务 蓝牙 随着蓝牙低功耗技术BLE(Bluetooth Low Energy)的发展,蓝牙技术正在一步步成熟,如今的大部分移动设备都配备有蓝牙4.0,相比之前的蓝牙技术耗电量大大降低.从iOS的 ...

  9. iOS开发——高级技术&GameCenter服务

    GameCenter服务 Game Center是由苹果发布的在线多人游戏社交网络,通过它游戏玩家可以邀请好友进行多人游戏,它也会记录玩家的成绩并在排行榜中展示,同时玩家每经过一定 的阶段会获得不同的 ...

随机推荐

  1. Quartus 的管脚分配

    与管脚分配相关的一些功能在assignments菜单下, Remove assignments... Back-Annotate Assignment... Import Assignment... ...

  2. 对需要聚类的数据使用canopy做初步的计算

    K值聚类的时候,需要自己指定cluster的数目. 这个cluster数目一般是通过canopy算法进行预处理来确定的. canopy具体描述可以参考这里. 下面是 golang语言的一个实现(对经纬 ...

  3. IDE警告信息不应该被忽略

    当ide进行编译时提示有变量未使用 可能意味着变量使用错误 因为我们没理由创建一个变量却不去使用他 如if语句判断一个int 或者日期 等其他非空类型是否为null 总是true 这意味这我们在逻辑处 ...

  4. Unicode explorer

    It can be cumbersome to work out some of the details of this by hand, so you can use the little Java ...

  5. 返回绝对值--Math.Abs 方法

    Math.abs()  返回指定数字的绝对值.

  6. WPF中获得控件相对于控件的相对位置

    GeneralTransform generalTransform = lstitem.TransformToAncestor(this.BackStack); Point point = gener ...

  7. canvas基本用法

    1.canvas和其他标签一样使用,但是IE8以下是不支持的,可以在canvas里面加一个span用来提示,例如: <canvas> <span>IE8不支持canvas< ...

  8. 使用 IntraWeb (38) - TIWAppForm、TIWForm、TIWBaseHTMLForm、TIWBaseForm

    窗体 TIWAppForm 所在单元及继承链: IWAppForm.TIWAppForm 主要成员: property OnURLRequest: TOnURLRequest //响应下面的 DoUR ...

  9. Odoo10 变化

    官方在 https://www.odoo.com/forum/help-1/question/fyi-what-has-odoo-r-d-been-working-on-lately-106945 发 ...

  10. Browser增加下载路径选择功能

    SWE Browser中有xml/download_settings_preferences.xml, 但在代码中却没有调用,导致“设置”中没有”选择下载路径“功能. 在com.android.bro ...