短信与邮件
调用系统内置的应用来发送短信、邮件相当简单,但是这么操作也存在着一些弊端:当你点击了发送短信(或邮件)操作之后直接启动了系统的短信(或邮件)应用程序,我们的应用其实此时已经处于一种挂起状态,发送完(短信或邮件)之后无法自动回到应用界面。如果想要在应用程序内部完成这些操作则可以利用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中的“发送”来完成短信发送工作,当然用户也可能点击“取消”按钮回到前一个短信编辑页面。
实现代码:
// // 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 ofType:nil]; NSURL *url=[NSURL fileURLWithPath:path]; [messageController addAttachmentURL:url withAlternateFilename:obj]; }]; } /*第三种方法*/ // NSString *path=[[NSBundle mainBundle]pathForResource:@"photo.jpg" ofType:nil]; // NSURL *url=[NSURL fileURLWithPath:path]; // NSData *data=[NSData dataWithContentsOfURL:url]; /** * attatchData:文件数据 * uti:统一类型标识,标识具体文件类型,详情查看:帮助文档中System-Declared Uniform Type Identifiers * fileName:展现给用户看的文件名称 */ // [messageController addAttachmentData:data typeIdentifier:@"public.image" filename:@"photo.jpg"]; } [self presentViewController:messageController animated:YES completion:nil]; } } #pragma mark - MFMessageComposeViewController代理方法 //发送完成,不管成功与否 -(void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result{ switch (result) { case MessageComposeResultSent: NSLog(@"发送成功."); break; case MessageComposeResultCancelled: NSLog(@"取消发送."); break; default: NSLog(@"发送失败."); break; } [self dismissViewControllerAnimated:YES completion:nil]; } @end
这里需要强调一下:
- MFMessageComposeViewController的代理不是通过delegate属性指定的而是通过messageComposeDelegate指定的。
- 可以通过几种方式来指定发送的附件,在这个过程中请务必指定文件的后缀,否则在发送后无法正确识别文件类别(例如如果发送的是一张jpg图片,在发送后无法正确查看图片)。
- 无论发送成功与否代理方法-(void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result都会执行,通过代理参数中的result来获得发送状态。
其实只要熟悉了MFMessageComposeViewController之后,那么用于发送邮件的MFMailComposeViewController用法和步骤完全一致,只是功能不同。下面看一下MFMailComposeViewController的使用:
// // KCSendEmailViewController.m // iOSSystemApplication // // Created by Kenshin Cui on 14/04/05. // Copyright (c) 2014年 cmjstudio. All rights reserved. // #import "KCSendEmailViewController.h" #import <MessageUI/MessageUI.h> @interface KCSendEmailViewController ()<MFMailComposeViewControllerDelegate> @property (weak, nonatomic) IBOutlet UITextField *toTecipients;//收件人 @property (weak, nonatomic) IBOutlet UITextField *ccRecipients;//抄送人 @property (weak, nonatomic) IBOutlet UITextField *bccRecipients;//密送人 @property (weak, nonatomic) IBOutlet UITextField *subject; //主题 @property (weak, nonatomic) IBOutlet UITextField *body;//正文 @property (weak, nonatomic) IBOutlet UITextField *attachments;//附件 @end @implementation KCSendEmailViewController - (void)viewDidLoad { [super viewDidLoad]; } #pragma mark - UI事件 - (IBAction)sendEmailClick:(UIButton *)sender { //判断当前是否能够发送邮件 if ([MFMailComposeViewController canSendMail]) { MFMailComposeViewController *mailController=[[MFMailComposeViewController alloc]init]; //设置代理,注意这里不是delegate,而是mailComposeDelegate mailController.mailComposeDelegate=self; //设置收件人 [mailController setToRecipients:[self.toTecipients.text componentsSeparatedByString:@","]]; //设置抄送人 if (self.ccRecipients.text.length>0) { [mailController setCcRecipients:[self.ccRecipients.text componentsSeparatedByString:@","]]; } //设置密送人 if (self.bccRecipients.text.length>0) { [mailController setBccRecipients:[self.bccRecipients.text componentsSeparatedByString:@","]]; } //设置主题 [mailController setSubject:self.subject.text]; //设置内容 [mailController setMessageBody:self.body.text isHTML:YES]; //添加附件 if (self.attachments.text.length>0) { NSArray *attachments=[self.attachments.text componentsSeparatedByString:@","] ; [attachments enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NSString *file=[[NSBundle mainBundle] pathForResource:obj ofType:nil]; NSData *data=[NSData dataWithContentsOfFile:file]; [mailController addAttachmentData:data mimeType:@"image/jpeg" fileName:obj];//第二个参数是mimeType类型,jpg图片对应image/jpeg }]; } [self presentViewController:mailController animated:YES completion:nil]; } } #pragma mark - MFMailComposeViewController代理方法 -(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
运行效果: