WKWebView(oc與js交互詳解)

目錄
-WKWebView 初始化
-WKWebView 加載資源
-WKWebView WKNavigationDelegate
-WKWebView 原生與JS交互實(shí)現(xiàn)
-WKWebView 第三方庫(kù)實(shí)現(xiàn)原理

一、WKWebView初始化
1、方法一,簡(jiǎn)單初始化
WKWebView *webView = [ [WKWebView alloc]initWithFrame:[UIScreen mainScreen].bounds];
2、方法二,使用WKWebViewConfiguration初始化
WKWebViewConfigration *webViewConfigration = [[WKWebViewConfigration alloc]init];
webViewConfigration.userContentController = [[WKUserContentController alloc]init];
WKWebView *webView = [ [WKWebView alloc]initWithFrame:[UIScreen mainScreen].bounds configration:webViewConfigration];

二、WKWebView 加載資源
1、加載網(wǎng)絡(luò)資源
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com/"];
NSURLRequest = [NSURLRequest requestWithURL:url];
[webView loadRequest:url];
2、加載本地資源
NSString *path = [[NSBundle mainBundle] pathForResource:@"index" type: @"HTML"];
NSString *htmlString = [NSString stringWithContentOfFile:path encoding: NSUTF8StringEncoding error:nil];
[webView loadHTMLString:htmlString baseURL:baseUrl];
請(qǐng)注意: 這里有坑!!有坑!!有坑?。?!如果是從Bundle獲取的文件是有問題的 移步這里http://www.lxweimin.com/p/92776cd5b098(雖然語言是swift寫的,問題是同樣的問題)

三、WKNavigationDelegate代理
1、 (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSLog(@"是否允許這個(gè)導(dǎo)航");
decisionHandler(WKNavigationActionPolicyAllow);
}
這個(gè)方法是加載網(wǎng)頁(yè)第一個(gè)執(zhí)行的方法,因?yàn)樗_定是否允許或者取消加載這個(gè)頁(yè)面。這里有一個(gè)枚舉WKNavigationActionPolicy,其結(jié)構(gòu)如下:
typedef NS_ENUM(NSInteger, WKNavigationActionPolicy) {
WKNavigationActionPolicyCancel,
WKNavigationActionPolicyAllow,
} API_AVAILABLE(macosx(10.10), ios(8.0));

  • (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
    // Decides whether to allow or cancel a navigation after its response is known.

    NSLog(@"知道返回內(nèi)容之后,是否允許加載,允許加載");
    //這個(gè)Block必須執(zhí)行,不然會(huì)崩潰
    decisionHandler(WKNavigationResponsePolicyAllow);
    }

2、 (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation {
NSLog(@"開始加載");
self.progress.alpha = 1;
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}
這個(gè)方法比較好理解,就是當(dāng)網(wǎng)頁(yè)內(nèi)容開始加載到web view的時(shí)候調(diào)用
3、(void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation {
NSLog(@"跳轉(zhuǎn)到其他的服務(wù)器");
}
這個(gè)代理方法了。我們知道了網(wǎng)頁(yè)是否允許加載,那么一旦不允許,那么這個(gè)加載過程就已經(jīng)結(jié)束了,不會(huì)再執(zhí)行其他的代理方法;如果允許,那么就會(huì)執(zhí)行開始加載的代理方法,執(zhí)行完開始加載的代理方法的時(shí)候再執(zhí)行這個(gè)代理方法
4、 (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
NSLog(@"網(wǎng)頁(yè)由于某些原因加載失敗");
self.progress.alpha = 0;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
5、 (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation {
NSLog(@"網(wǎng)頁(yè)開始接收網(wǎng)頁(yè)內(nèi)容");
}
這個(gè)代理方法是在網(wǎng)頁(yè)開始接受網(wǎng)絡(luò)內(nèi)容的時(shí)候調(diào)用
6、(void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
NSLog(@"網(wǎng)頁(yè)導(dǎo)航加載完畢");
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
self.title = webView.title;
[webView evaluateJavaScript:@"document.title" completionHandler:^(id _Nullable ss, NSError * _Nullable error) {
NSLog(@"----document.title:%@---webView title:%@",ss,webView.title);
}];
self.progress.alpha = 0;
}
網(wǎng)頁(yè)已經(jīng)加載完畢會(huì)調(diào)用這個(gè)代理方法
7、 (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
NSLog(@"加載失敗,失敗原因:%@",[error description]);
self.progress.alpha = 0;
}
網(wǎng)頁(yè)加載失敗會(huì)調(diào)用的代理
8、 (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
NSLog(@"網(wǎng)頁(yè)加載內(nèi)容進(jìn)程終止");
}
9、 (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation {

}
網(wǎng)頁(yè)重定向會(huì)調(diào)用

四、WKWebView 原生與JS交互實(shí)現(xiàn)
1、js給原生發(fā)送消息
方法一,js通過觸發(fā)URL的方式,定義一套協(xié)議頭,把參數(shù)拼接到URL后面,然后WKWebView通過攔截URL,做到傳值效果,但是不能立馬拿到返回值,因?yàn)閖s是單線程的,而在原生里面則是多線程,如果要想拿到返回值,需要等到原聲回調(diào)js函數(shù)才能拿到
上代碼:
js代碼,簡(jiǎn)單點(diǎn)的吧
<a href="webview://login?username=xiaoming&password=123456">點(diǎn)我去原生登陸</a>
oc代碼,WKWebViewNavigationDelegate代理方法

  • (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    NSURL url = navigation.request.url;
    if ([[url scheme] isEqualToString: @"webview"]) {
    //取出拼接在URL后面的參數(shù)
    NSString *string = url.absoluteString;
    NSArray *array = [string compoentsSeparatedByString:@"?"];
    if(array.count>0){
    if([array[0] isEqualToString:@"login"]) {
    //獲取登陸 參數(shù)
    NSMutableDictionary * parameters = [NSMutableDictionary Dictionary];
    for(NSString *str in [array.lastObject compoentsSeparatedByString:@"&"]) {
    NSArray * parameter = [str compoentsSeparatedByString:@"="];
    parameters[parameter.firstObject] = parameter.lastObject;
    }

    }
    decisionHandler(WKNavigationActionPolicyCancel);
    return;
    }
    decisionHandler(WKNavigationActionPolicyAllow);
    }

方法二、通過js通過調(diào)用這個(gè)函數(shù)來給wkwebview發(fā)送消息 window.webkit.messageHandlers.<name>.postMessage(<messageBody>) ,在WKUserContentController.h 文件中有介紹,其中<name>為協(xié)議的名稱,<messageBody>為發(fā)送消息要傳的參數(shù)
例如,:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>oc與JS交互傳值Demo</title>
<script>
function sendMessage() {
alert('lll');
var name = 'xiaoming';
var password = '123456';
window.webkit.login.postMessage({'name':name,'password':password});
}
window.onload = function () {
let btn = document.getElementById('btn');
btn.onclick = sendMessage;
}
</script>
</head>
<body>
<input type="button" value="發(fā)消息去" id="btn">
</body>
</html>
這是一個(gè)簡(jiǎn)單的html
oc中接收js消息代碼
//初始化
WKWebViewConfigration *webViewConfigration = [[WKWebViewConfigration alloc]init];
webViewConfigration.userContentController = [[WKUserContentController alloc]init];
webViewConfigration.userContentController
WKWebView *webView = [ [WKWebView alloc]initWithFrame:[UIScreen mainScreen].bounds configration:webViewConfigration];
//添加一個(gè)協(xié)議
[webViewConfigration.userContentController addScriptMessageHandler:self name:@"login"];
self必須遵守WKScriptMessageHandler協(xié)議并實(shí)現(xiàn)方法
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
//messag.name為協(xié)議的名字"login"
//message.body為js傳過來的值
}

2、oc給js發(fā)送消息
采用蘋果提供的接口,可以動(dòng)態(tài)注入js代碼,也能調(diào)用js方法
oc代碼如下:
[_webView evaluateJavaScript:@"outLogin(true)" completionHandler:^(id _Nullable meassge, NSError * _Nullable error) {
//消息執(zhí)行完成的回調(diào)
}];
js代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>oc與JS交互傳值Demo</title>
<script>
function outLogin(meassge) {
//退出登錄,清理緩存
return true;
}
</script>
</head>
<body>
</body>
</html>
先到此下一篇講WKWebViewJavaScriptBridge解析,也是基于原生代碼的封裝

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,460評(píng)論 6 538
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,067評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 177,467評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,468評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,184評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,582評(píng)論 1 325
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,616評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,794評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,343評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,096評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,291評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,863評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,513評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,941評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,190評(píng)論 1 291
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,026評(píng)論 3 396
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,253評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容

  • 前言 上一篇專門講解了WKWebView相關(guān)的所有類、代理的所有API。前篇文章地址:http://blog.cs...
    iwolfox閱讀 1,115評(píng)論 1 1
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 29,485評(píng)論 8 265
  • 前言 關(guān)于UIWebView的介紹,相信看過上文的小伙伴們,已經(jīng)大概清楚了吧,如果有問題,歡迎提問。 本文是本系列...
    CoderLF閱讀 9,007評(píng)論 2 12
  • WKWebView是在Apple的WWDC 2014隨iOS 8和OS X 10.10出來的,是為了解決UIWeb...
    zhYx_閱讀 22,688評(píng)論 4 19
  • 微微的例假推遲快要一周了,望著潔白的天花板,心里暗暗數(shù)著上次來的日子,又誠(chéng)惶誠(chéng)恐地計(jì)算著她和老喬愛愛的日子,微微輕...
    xingzoujianghu閱讀 248評(píng)論 0 1