iOS學習筆記28-系統服務(一)簡訊和郵件
一、系統應用
在開發某些應用時,我們可能希望能夠調用iOS系統內建的電話、簡訊、郵件、瀏覽器應用,或者直接調用安裝的第三方應用,這個要怎麼實現呢?
這裡統一使用UIApplication的一個對象方法來實現:
//開啟不同的系統應用- (void)openUrl:(NSURL *)url;
那怎麼區分我是要打電話還是發簡訊等等呢?
之前我們學習網路的時候,是不是URL最前面使用的是http://,使用本地檔案是不是前面就變成file://了,這就是URL的協議,我們就是控制URL的協議,來開啟不同應用。
下面列出了一些系統應用URL協議:
tel://和
tel::
打電話,沒有提示直接撥打
telprompt://和
telprompt::
打電話,撥打到電話前有提示使用者是否撥打到電話
sms://和
sms::
發簡訊
mailto://和
mailto::
發郵件
http://和
http::
開啟瀏覽器下面就是具體執行個體示範:1. 有提示的打電話
//打電話- (void)telpromptTest{ //電話號碼 NSString *phoneNumber = @"18500138888"; //1.建立打電話URL路徑,這種方式會提示使用者確認是否撥打到電話 NSString *urlStr = [NSString stringWithFormat:@"telprompt://%@",phoneNumber]; //2.產生URL NSURL *url = [NSURL URLWithString:urlStr]; //3.開啟系統應用 UIApplication *application = [UIApplication sharedApplication]; [application openURL:url];}
2. 發簡訊
//傳送簡訊- (void)sendMessageTest{ //電話號碼 NSString *phoneNumber = @"18500138888"; //1.建立發簡訊URL路徑 NSString *urlStr = [NSString stringWithFormat:@"sms://%@",phoneNumber]; //2.產生URL NSURL *url = [NSURL URLWithString:urlStr]; //3.開啟系統應用 UIApplication *application = [UIApplication sharedApplication]; [application openURL:url];}
3. 發郵件
//發送郵件- (void)sendEmailTest { NSString *mailAddress = @"850192964@qq.com"; //1.建立發郵件URL路徑 NSString *urlStr = [NSString stringWithFormat:@"mailto://%@",mailAddress]; //2.產生URL NSURL *url = [NSURL URLWithString:urlStr]; //3.開啟系統應用 UIApplication *application = [UIApplication sharedApplication]; [application openURL:url];}
4. 開啟瀏覽器
//瀏覽網頁- (void)browserTest { //1.建立開啟瀏覽器URL路徑 NSString *urlStr = @"http://www.baidu.com"; //2.產生URL NSURL *url = [NSURL URLWithString:urlStr]; //3.開啟系統應用 UIApplication *application = [UIApplication sharedApplication]; [application openURL:url];}
上面開啟的是系統應用,實際上openUrl的功能是只要是系統安裝了的應用程式,都可以開啟,比如假設你現在開發了一個應用A,如果使用者機器上已經安裝了此應用,並且在應用B中希望能夠直接開啟A,也是可以用openUrl實現,不過要進行一些配置。
配置第三方應用步驟:修改應用A的
info.plist檔案,添加
URL types節點 在該節點下,配置具體協議
URL Schemas以及應用A的唯一標識
URL identifier,如:
在應用A的
AppDelegate檔案中處理
AppDelegate的一個代理方法
/* 當被其他應用程式通過URL開啟時就會調用, 這裡可以接收參數並解析,返回是否能被其他應用程式開啟 */-(BOOL)application:(UIApplication *)application //當前應用程式 openURL:(NSURL *)url //其他應用使用的URL sourceApplication:(NSString *)sourceApplication //其他應用的應用標識 annotation:(id)annotation{ NSLog(@"url:%@",url); NSLog(@"source:%@",sourceApplication); NSLog(@"params:%@",[url host]); return YES;//是否開啟}
配置應用A完成,然後我們就可以在應用B中使用
openUrl開啟應用A了
//開啟第三方應用- (void)thirdPartyApplicationTest { //使用第三方應用協議 NSString *urlStr = @"cmj://myparams"; NSURL *url = [NSURL URLWithString:urlStr]; //判斷該應用是否能開啟 UIApplication *application = [UIApplication sharedApplication]; if(![application canOpenURL:url]){ NSLog(@"無法開啟\"%@\",請確保此應用已經正確安裝.",url); return; } [application openURL:url];}
二、系統服務
調用系統內建的應用來傳送簡訊、郵件相當簡單,但是這麼操作也存在著一些弊端:
當你點擊了傳送簡訊(或郵件)操作之後,直接啟動了系統的簡訊(或郵件)應用程式,我們的應用其實此時已經處於一種掛起狀態,發送完(簡訊或郵件)之後無法自動回到應用介面。
如果想要在應用程式內部完成這些操作,則可以利用iOS中的MessageUI.framework,它提供了關於簡訊和郵件的UI介面供開發人員在應用程式內部調用。
MessageUI.framework提供了有現成的簡訊和郵件的編輯介面,開發人員只需要通過編程的方式給簡訊和郵件控制器設定對應的參數即可。
1、簡訊
在MessageUI.framework中使用MFMessageComposeViewController來發簡訊
下面是使用步驟:匯入
MessageUI.framework,並添加標頭檔
#import
建立
MFMessageComposeViewController對象 設定收件者、資訊本文等內容屬性,設定代理
messageComposeDelegate 以模態彈出該視圖控制器 處理代理方法,擷取發送狀態:
/* 發送完成會調用,不管成功與否 */-(void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result;/*發送結果*/
下面是使用執行個體:
#import "KCSendMessageViewController.h"#import @interface KCSendMessageViewController ()@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]){ return; } //建立簡訊發送視圖控制器 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]) { //添加附件,請務必指定附件檔案的尾碼,否則在發送後無法正確識別檔案類別 NSArray *attachments = [self.attachments.text componentsSeparatedByString:@","]; if (attachments.count > 0) { for(NSString *attachment in attachments){ NSString *path = [[NSBundle mainBundle] pathForResource:attachment ofType:nil]; NSURL *url = [NSURL fileURLWithPath:path]; //添加附件具體方法,需要設定附件URL和附件的標識 [messageController addAttachmentURL:url withAlternateFilename:attachment]; }; } } //以模態彈出介面 [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
2. 郵件
在MessageUI.framework中使用MFMailComposeViewController來發郵件
使用步驟【和發簡訊相似】:匯入
MessageUI.framework,並添加標頭檔
#import
建立
MFMailComposeViewController對象 設定收件者、抄送人、本文等內容屬性,設定代理
mailComposeDelegate 以模態彈出該視圖控制器 處理代理方法,擷取發送狀態:
/* 發送完成會調用,不管成功與否 */-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result /* 發送結果 */ error:(NSError *)error;/* 錯誤資訊 */
下面是執行個體:
#import "KCSendEmailViewController.h"#import @interface KCSendEmailViewController ()@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]) { return; } //建立發送郵件視圖控制器 MFMailComposeViewController *mailController = [[MFMailComposeViewController alloc] init]; //設定代理,注意這裡不是delegate,而是mailComposeDelegate mailController.mailComposeDelegate = self; //設定收件者 NSArray *recipients = [self.toTecipients.text componentsSeparatedByString:@","]; [mailController setToRecipients:recipients]; //設定抄送人 if (self.ccRecipients.text.length > 0) { NSArray *ccRecipients = [self.ccRecipients.text componentsSeparatedByString:@","]; [mailController setCcRecipients:ccRecipients]; } //設定密送人 if (self.bccRecipients.text.length > 0) { NSArray *bccRecipients = [self.bccRecipients.text componentsSeparatedByString:@","]; [mailController setBccRecipients:bccRecipients]; } //設定主題 [mailController setSubject:self.subject.text]; //設定主體內容 [mailController setMessageBody:self.body.text isHTML:YES]; //添加附件 if (self.attachments.text.length > 0) { NSArray *attachments = [self.attachments.text componentsSeparatedByString:@","] ; for(NSString *attachment in attachments) { NSString *file = [[NSBundle mainBundle] pathForResource:attachment ofType:nil]; NSData *data = [NSData dataWithContentsOfFile:file]; //第一個參數是附件資料,第二個參數是mimeType類型,jpg圖片對應image/jpeg [mailController addAttachmentData:data mimeType:@"image/jpeg" fileName:attachment]; }]; } //彈出視圖 [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