鑒于UIWebView的內(nèi)存問題,新項(xiàng)目選擇了WKWebView來加載URL詳情頁面甩栈,本文將圍繞“加載URL詳情頁面爆惧,并確保內(nèi)部鏈接正常跳轉(zhuǎn)”的需求,細(xì)聊開發(fā)過程中遇到的問題路捧。(注:本文不涉及js交互、緩存相關(guān)的內(nèi)容)
一传黄、WKWebView的基本使用
1杰扫、加載指定的URL
- (void)gotoWebViewWithUrl:(NSString *)Url
{
WKWebView *webview = [[WKWebView alloc]initWithFrame:self.view.bounds];
[webview loadRequest:[NSURL URLWithString: Url];
}
2、代理
(1) WKNavigationDelegate
// 準(zhǔn)備加載頁面
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;
// 內(nèi)容開始加載
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;
// 頁面加載完成
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
// 頁面加載失敗
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;
// 收到服務(wù)器重定向請(qǐng)求
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;
// 在收到響應(yīng)開始加載后膘掰,決定是否跳轉(zhuǎn)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
// 在請(qǐng)求開始加載之前章姓,決定是否跳轉(zhuǎn)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
(2) WKUIDelegate
?JS交互時(shí)會(huì)用到這個(gè)代理,本文討論的需求不涉及JS交互识埋,所以這里不在贅述凡伊。
二、問題及解決方案
1窒舟、黑屏閃現(xiàn)
問題描述: 執(zhí)行[webview loadRequest:]加載URL頁面時(shí)系忙,偶爾會(huì)有黑屏閃現(xiàn)的現(xiàn)象。
?解決方案: 在初始化webView時(shí)惠豺,加載一個(gè)空白頁面银还。
// 加載空白頁
- (void)loadBlankHtml
{
static NSString *blankHtmlStr = @"<!DOCTYPE html>\
<html lang=\"en\">\
<head>\
<meta charset=\"UTF-8\">\
<title>Document</title>\
<style>body{background-color: #111111;}</style>\
</head>\
<body></body>\
</html>";
[self.webView loadHTMLString:blankHtmlStr baseURL:[NSURL URLWithString:kAboutBlank]];
}
2、加載進(jìn)度洁墙、加載超時(shí)問題
問題描述:
??點(diǎn)擊webView的某個(gè)鏈接跳轉(zhuǎn)至新的頁面時(shí)蛹疯,會(huì)異步的觸發(fā)N個(gè)請(qǐng)求(多次觸發(fā)回調(diào)1)來獲取頁面的多個(gè)模塊數(shù)據(jù),其中某些請(qǐng)求可能不會(huì)響應(yīng)(不會(huì)觸發(fā)回調(diào)2)热监,某些請(qǐng)求可能不會(huì)有成功捺弦、失敗的回調(diào)。
??所以,無法通過監(jiān)聽請(qǐng)求的開始羹呵、結(jié)束獲取加載進(jìn)度骂际,判斷加載超時(shí)。
// 回調(diào)1: 在請(qǐng)求開始加載之前冈欢,決定是否跳轉(zhuǎn)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
// 回調(diào)2: 在收到響應(yīng)開始加載后歉铝,決定是否跳轉(zhuǎn)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
解決方案:請(qǐng)求觸發(fā)回調(diào)2方法后才算真正的開始,展示進(jìn)度條凑耻、啟動(dòng)超時(shí)檢測(cè)太示,請(qǐng)求有成功、失敗的返回時(shí)香浩,隱藏進(jìn)度條类缤、停止超時(shí)檢測(cè)。
// 在收到響應(yīng)開始加載后邻吭,決定是否跳轉(zhuǎn)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
if (NO == self.progressView.hidden) {
[self restartOutTimer];
self.progressView.hidden = hide;
}
if (decisionHandler) {
decisionHandler(WKNavigationResponsePolicyAllow);
}
}
3餐弱、加載超時(shí)處理
問題描述:
?加載超時(shí)或沒有網(wǎng)絡(luò)時(shí),需要在頁面中告知用戶囱晴,同時(shí)不影響現(xiàn)有的webView頁面層級(jí)關(guān)系膏蚓。(例如,加載頁面后斷網(wǎng)畸写,點(diǎn)擊頁面內(nèi)鏈接驮瞧,需要告知用戶沒有網(wǎng)絡(luò),用戶可以通過返回按鈕返回到剛才的頁面)
?解決方案: 加載本地html頁面枯芬。
// 在請(qǐng)求開始加載之前论笔,決定是否跳轉(zhuǎn)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSString* requestUrl = [navigationAction.request.URL absoluteString];
// 沒有網(wǎng)絡(luò)時(shí),展示本地url頁面
if (self.curNetworkStatus == NetworkNotReachable &&
navigationAction.navigationType != WKNavigationTypeBackForward) {
NSString *path = [[NSBundle mainBundle] pathForResource:@"NoNetwork" ofType:@"html"];
if (![requestUrl isEqualToString:self.rootUrl]) {
[self loadFileURLWithPath:path];
} else {
[self loadHTMLStringWithPath:path];
}
decisionHandler(WKNavigationActionPolicyCancel);
}
}
3千所、跳轉(zhuǎn)App Store問題
WKWebView不支持https://itunes.apple.com/cn/app/id******這樣的鏈接跳轉(zhuǎn)App Store狂魔,需要做出如下的處理才能正常跳轉(zhuǎn)。
// 在請(qǐng)求開始加載之前調(diào)用淫痰,決定是否跳轉(zhuǎn)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
// itunes跳轉(zhuǎn)鏈接需要單獨(dú)處理
if ([[navigationAction.request.URL host] isEqualToString:@"itunes.apple.com"] &&
[[UIApplication sharedApplication] openURL:navigationAction.request.URL]) {
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}