WebKit 打電話失敗的問題

關于WebKit

最近接手的一個app頁面全部用H5寫的,使用的是WebKit框架。我之前寫的app也有H5頁面,不過只有兩頁,用的是webView,全H5寫app用WebKit是很有必要的,在這里推薦兩篇文章快速了解WebKit:
iOS 8 WebKit框架概覽(上)
iOS 8 WebKit框架概覽(下)

打電話失敗

然后,問題來啦。app有聯系客服功能,點擊客服電話,發現電話打不出去。

*注:電話打不出去的意思是壓根沒有調用電話這個功能,不是沒人接啊~ *
題外話: 最近電話號碼13585904041很火,我也拿來用一下

通過控制臺Log可以發現,請求失敗了:

#pragma mark 頁面加載失敗之后調用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
   NSLog(@"頁面加載失敗:\n %@",error); 
}

頁面加載失?。?br> Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={_WKRecoveryAttempterErrorKey=<WKReloadFrameErrorRecoveryAttempter: 0x7fe7f3d7a3c0>, NSErrorFailingURLStringKey=tel:13585904041, NSErrorFailingURLKey=tel:13585904041, NSUnderlyingError=0x7fe7f3d6e260 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "unsupported URL" UserInfo={NSErrorFailingURLStringKey=tel:13585904041, NSLocalizedDescription=unsupported URL, NSErrorFailingURLKey=tel:010-57745342}}, NSLocalizedDescription=unsupported URL}

看這些Log不要頭暈啊,總而言之一句話,不支持打開 tel:13585904041 這個URL,到這里,我們先復習一下打電話的代碼。

iOS打電話的代碼

方法一:
 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://10010"]];//打電話```

使用openURL這個API打電話結束后,返回的是系統的撥打電話界面,如何才能返回自己的應用呢?看下面的方法。

#####方法二:
使用UIWebView加載電話,這種是合法的,可以上App Store的。

    UIWebView *callWebview =[[UIWebView alloc] init];
    NSURL *telURL =[NSURL URLWithString:@"tel:13585904041"];
    [callWebview loadRequest:[NSURLRequest requestWithURL:telURL]];
    //記得添加到view上
    [self.view addSubview:callWebview];
還有一種是私有方法,不能上App Store的(自己沒試過,有求真精神的可以試試然后告訴我被拒沒)。 

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"telprompt://10010"]];```

到這里我們可以發現UIWebView是可以打開 tel:13585904041 的,但是,很明顯,WebKit框架里的WKWebView不支持 打開tel:XXX 這種URL。

解決方法

通過打斷點,可以發現打開一個url大概需要依次走以下代理方法(不全):

#pragma mark 在發送請求之前,決定是否跳轉
-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
      NSLog(@"在收到響應前,決定是否跳轉");
      decisionHandler(WKNavigationActionPolicyAllow);//允許跳轉
}

#pragma mark 頁面開始加載時調用
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
    NSLog(@"頁面開始加載");
}

#pragma mark  頁面加載完成之后調用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
{
    NSLog(@"頁面加載完成");
}

#pragma mark 頁面加載失敗之后調用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
    NSLog(@"頁面加載失敗:\n %@",error);
}

在加載一個頁面之前會先決定是否跳轉,我剛開始設置所有的請求都允許加載,收到@"tel:13585904041"請求后,就進到didStartProvisionalNavigation方法開始打開這個URL,然后就失敗了,所以我們需要截掉tel請求。

修改后的代理方法:

#pragma mark 在發送請求之前,決定是否跳轉
-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    NSLog(@"在收到響應前,決定是否跳轉");

    NSString *urlString = [[navigationAction.request URL] absoluteString];
    urlString = [urlString stringByRemovingPercentEncoding];//解析url
        
    if ([urlString hasPrefix:@"tel"])//截獲電話請求
    {
        //取消WKWebView 打電話請求
        decisionHandler(WKNavigationActionPolicyCancel);
        //用openURL 這個API打電話
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString: urlString];
    }
    else
    {
        decisionHandler(WKNavigationActionPolicyAllow);//允許其他請求
    }
}

修改后就解決啦~

對純H5的吐槽

即使WebKit比WebView性能好些,但是純H5頁面還是卡死的感覺,用戶體驗很不好,兼容性也不好(快速開發的省的時間都用來調兼容了然而并沒有什么卵用),最后吐槽一句,界面好丑,一點蘋果的風格都沒了,然后,我們,決定用React Native了~

文章有錯誤或者不嚴謹的地方,敬請大家指出,我將及時改正。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,229評論 4 61
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,274評論 25 708
  • 贊美女人如花 因為花開千嬌百媚 但別忘了花兒容易枯萎 保持魅力無限的女人 唯有選擇學做一個優雅的女人 優雅的女人有...
    胡楊公主閱讀 399評論 10 7
  • 最近這個月我換了新工作以后,幾乎每天我不是會接觸保險,就是會思考保險,所以我一直在想保險到底是什么。今天早上我的腦...
    百合兒閱讀 192評論 2 2
  • 1.黑同伴然后黑自己; 2.關聯聯想嫁接,內心戲一部甄嬛傳,說出來只是一段廣告的時間; 3.修改成語歇后語; 4....
    ZhangYY閱讀 242評論 0 0