Fork me on GitHub

iOS与JS(一):使用URL拦截的方式进行JS与OC互相调用

关于WKWebViewUIWebView之间的区别,本文就不在说明,本文只使用WKWebView
效果图如下:

html代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<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>这是按钮调用</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>这是回调结果展示区</h1>
<textarea id ="returnValue" type="value" rows="5" cols="50"></textarea>

</body>
</html>

以获取定位这个按钮为例说明OC和JS互相调用代码执行流程:

  1. 初始化WKWebView加载本地html文件。
  2. 点击web中的按钮,web发起URL请求。
  3. URL请求被WKNavigationDelegate中的代理方法拦截。根据自定义的URL识别使用不同的处理方式。如:在- (void)getLocation方法中调用JS的setLocation函数。
  4. JS的setLocation函数执行JS的alert()函数,被WKUIDelegate中的代理方法捕获,调用iOS原生的弹框。

详细代码说明

  • 初始化WKWebView加载本地html文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    - (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的一些参数配置
    • 2 加载本html
  • URL请求被WKNavigationDelegate中的代理方法拦截。也就是JS调用了OC

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #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 调用 JS

    1
    2
    3
    4
    5
    6
    7
    8
    - (void)getLocation
    {
    // 将结果返回给js
    NSString *jsStr = [NSString stringWithFormat:@"setLocation('%@')",@"上海市浦东新区"];
    [self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) {
    NSLog(@"%@----%@",result, error);
    }];
    }
    • JS代码被当成字符串调用
    • completionHandler是JS代码被调用后回调
  • JS中alert弹窗被WKUIDelegate中的代理方法捕获,调用iOS原生的弹框。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #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可以直接调用iOS的图片库,相机和文件。

代码: 90-iOSJS/OCJS1

参考:

坚持原创技术分享,您的支持将鼓励我继续创作!
  • 本文标题: iOS与JS(一):使用URL拦截的方式进行JS与OC互相调用
  • 本文作者: AndyRon
  • 发布时间: 2017年09月06日 - 00:00
  • 最后更新: 2018年09月16日 - 17:07
  • 本文链接: http://andyron.com/2017/ios-js-1.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!