在開發某些應用時,我們可能希望能夠調用iOS系統內置的電話、短信、郵件、浏覽器應用,或者直接調用安裝的第三方應用,這個要怎麼實現呢?
//打開不同的系統應用
- (void)openUrl:(NSURL *)url;
那怎麼區分我是要打電話還是發短信等等呢?
之前我們學習網絡的時候,是不是URL最前面使用的是http://
,使用本地文件是不是前面就變成file://
了,這就是URL的協議,我們就是控制URL的協議,來打開不同應用。
tel://
和tel:
:打電話,沒有提示直接撥打 telprompt://
和telprompt:
:打電話,撥打電話前有提示用戶是否撥打電話 sms://
和sms:
:發短信 mailto://
和mailto:
:發郵件 http://
和http:
:打開浏覽器
//打電話
- (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];
}
//發送短信
- (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];
}
//發送郵件
- (void)sendEmailTest {
NSString *mailAddress = @"[email protected]";
//1.創建發郵件URL路徑
NSString *urlStr = [NSString stringWithFormat:@"mailto://%@",mailAddress];
//2.生成URL
NSURL *url = [NSURL URLWithString:urlStr];
//3.打開系統應用
UIApplication *application = [UIApplication sharedApplication];
[application openURL:url];
}
//浏覽網頁
- (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
實現,不過要進行一些配置。
info.plist
文件,添加URL types
節點 在該節點下,配置具體協議URL Schemas
以及應用A的唯一標識URL identifier
,如下圖: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;//是否打開
}
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
提供了有現成的短信和郵件的編輯界面,開發人員只需要通過編程的方式給短信和郵件控制器設置對應的參數即可。
在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
在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