參考:
關(guān)于WKWebView與UIWebView之間的區(qū)別,本文就不在說明,本文只使用WKWebView。
效果圖如下:

html代碼:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<script language="javascript">
function loadURL(url) {
window.location.href = url
}
function locationClick() {
loadURL("scheme://getLocation");
}
function shake() {
loadURL("scheme://shake");
}
function setLocation(location) {
alert(location)
document.getElementById("returnValue").value = location;
}
</script>
</head>
<body>
<h1>這是按鈕調(diào)用</h1>
<input type="button" value="獲取定位" onclick="locationClick()" /><br><br>
<input type="button" value="震動一下" onclick="shake()" /><br><br>
<h1>這是文件上傳</h1>
<input type="file" /><br><br>
<h1>這是回調(diào)結(jié)果展示區(qū)</h1>
<textarea id ="returnValue" type="value" rows="5" cols="50"></textarea>
</body>
</html>
以獲取定位這個按鈕為例說明OC和JS互相調(diào)用代碼執(zhí)行流程:
- 初始化
WKWebView加載本地html文件。 - 點擊web中的按鈕,web發(fā)起URL請求。
- URL請求被
WKNavigationDelegate中的代理方法攔截。根據(jù)自定義的URL識別使用不同的處理方式。如:在- (void)getLocation方法中調(diào)用JS的setLocation函數(shù)。 - JS的
setLocation函數(shù)執(zhí)行JS的alert()函數(shù),被WKUIDelegate中的代理方法捕獲,調(diào)用iOS原生的彈框。
詳細代碼說明
-
初始化
WKWebView加載本地html文件- (void)initWKWebView { // 1 WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init]; configuration.userContentController = [WKUserContentController new]; WKPreferences *preferences = [WKPreferences new]; preferences.javaScriptCanOpenWindowsAutomatically = YES; preferences.minimumFontSize = 40.0; configuration.preferences = preferences; self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration]; // 2 NSString *urlStr = [[NSBundle mainBundle] pathForResource:@"index.html" ofType:nil]; NSURL *fileURL = [NSURL fileURLWithPath:urlStr]; [self.webView loadFileURL:fileURL allowingReadAccessToURL:fileURL]; self.webView.navigationDelegate = self; self.webView.UIDelegate = self; [self.view addSubview:self.webView]; }- 1
WKWebView的一些參數(shù)配置 - 2 加載本html
- 1
-
URL請求被
WKNavigationDelegate中的代理方法攔截。也就是JS調(diào)用了OC#pragma mark - WKNavigationDelegate - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { NSURL *URL = navigationAction.request.URL; NSString *scheme = [URL scheme]; if ([scheme isEqualToString:@"scheme"]) { [self handleCustomAction:URL]; decisionHandler(WKNavigationActionPolicyCancel); return; } decisionHandler(WKNavigationActionPolicyAllow); } -
OC 調(diào)用 JS
- (void)getLocation { // 將結(jié)果返回給js NSString *jsStr = [NSString stringWithFormat:@"setLocation('%@')",@"上海市浦東新區(qū)"]; [self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) { NSLog(@"%@----%@",result, error); }]; }- JS代碼被當成字符串調(diào)用
-
completionHandler是JS代碼被調(diào)用后回調(diào)
-
JS中alert彈窗被
WKUIDelegate中的代理方法捕獲,調(diào)用iOS原生的彈框。#pragma mark - WKUIDelegate - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler { UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提醒" message:message preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { completionHandler(); }]]; [self presentViewController:alert animated:YES completion:nil]; }
最后,html中的文件input可以直接調(diào)用iOS的圖片庫,相機和文件。

代碼: 90-iOSJS/OCJS1