iOS开发iOS开发常用知识点iOS 开发每天分享优质文章

iOS,WKWebView加载HTML与JS交互。

2018-09-13  本文已影响18人  ProgrammerChan
由于项目使用到了oc与js混编,oc与js交互可以用UIWebView也可以用WKWebView,这里我说一下通过WKWebView加载HTML(本地/网络)文件来进行交互,官方推荐在嵌入h5页面或者需要交互的时候都使用WKWebView而不是使用UIWebView。WKWebView需要最低系统为8.0。

一:加载HTML

加载wkWebView的时候可以设置很多配置参数。需要用到的地方会写。

    _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];

    //设置代理用来获取加载状态等等信息...<WKUIDelegate,WKNavigationDelegate>
    _webView.UIDelegate = self;
    _webView.navigationDelegate = self;
    [self.view addSubview:_webView];
    //加载本地html
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"testFunction" ofType:@"html"];
    [_webView loadFileURL:[NSURL fileURLWithPath:filePath] allowingReadAccessToURL:[NSBundle mainBundle].resourceURL];

二:OC调用JS

oc如果需要调用js方法。需要在html加载完成的代理方法中实现。

//html加载失败
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
    NSLog(@"error message:%@",error);
}

//html开始加载
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
    NSLog(@"begin load html");
}

//html加载完成
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    NSLog(@"finish load");
    WEAKSELF;
    [webView evaluateJavaScript:@"" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
        
        NSLog(@"response: %@ error: %@", response, error);
    }];
}

这里大概3种情况。
1.oc调用js无参数函数。
2.oc调用js有参数函数。
3.oc调用js函数后,有返回值。

html代码。

<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>walletProj</title>
</head>
<body>
    <script type="text/javascript">

        //无参数函数
        function testA() {
            alert("a");
        }

        //有参数函数
        function testB(value) {
            alert(value);
        }

        function testC(value) {

            //返回值可以是很多类型。

            //反馈字符串
            return value + "value";

            //返回对象,如果需要传递给oc的东西有很多,就可以构造一个这样的对象用来传输。
            // var finalObj = {"name":"chaman","age":"18","sex":"male"};
            // return finalObj;
        }

    </script>
</body>
</html>

OC代码。

注意:在wkwebView中如果html有弹框处理(alert函数),oc这边是不能显示的,必须实现代理方法- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler。
从中获取alert内容并做处理。

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    NSLog(@"finish load");
    
    //调用js无参函数
    [webView evaluateJavaScript:@"testA()" completionHandler:^(id _Nullable response, NSError * _Nullable error) {

        //js函数调用return,这里才会有东西,否则无任何信息。
        NSLog(@"response: %@ error: %@", response, error);
    }];
    
    //调用js有参函数
    [webView evaluateJavaScript:[NSString stringWithFormat:@"testB('%@')",@"show"] completionHandler:^(id _Nullable response, NSError * _Nullable error) {

        //js函数调用return,这里才会有东西,否则无任何信息。
        NSLog(@"response: %@ error: %@", response, error);
    }];
    
    //调用js有参函数并获得返回值
    [webView evaluateJavaScript:[NSString stringWithFormat:@"testC('%@')",@"return value"] completionHandler:^(id _Nullable response, NSError * _Nullable error) {

        //js函数调用return,这里才会有东西,否则无任何信息。
        NSLog(@"response: %@ error: %@", response, error);
    }];
}

二:JS调用OC

比如我OC有一个方法叫"jsCallOc",JS在某些场景需要调用OC的这个函数。
1.oc需要注册"jsCallOc"这个方法,在初始化WKWebView的时候注入进去,这时候初始化WKWebView就应该这样写,需要实现WKScriptMessageHandler代理。

    //注册方法
    WKUserContentController *userContentController = [[WKUserContentController alloc] init];
   //需要实现<WKScriptMessageHandler>,可同时注册多个方法名字,但是记得在控制器销毁时候移除。
    [userContentController addScriptMessageHandler:self name:@"jsCallOc"];
    
    // WKWebView的配置
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    configuration.userContentController = userContentController;
    
    _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 10, 10) configuration:configuration];
    //设置代理用来获取加载状态等等信息...<WKUIDelegate,WKNavigationDelegate>
    _webView.UIDelegate = self;
    _webView.navigationDelegate = self;
    [self.view addSubview:_webView];
    //加载本地html
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"testFunction" ofType:@"html"];
    [_webView loadFileURL:[NSURL fileURLWithPath:filePath] allowingReadAccessToURL:[NSBundle mainBundle].resourceURL];

2.实现代理方法获取js调用的操作。

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
    //获取值
    NSLog(@"data:%@", message.body);
    
    //获取函数名字
    NSLog(@"data:%@", message.name);
}

JS代码(JS调用OC需要按照特定格式:window.webkit.messageHandlers.<方法名>.postMessage(<数据>))

<head>
    <meta charset="UTF-8">
    <title>walletProj</title>
</head>

<body>
    <script type="text/javascript">

        //无参数函数
        function testA() {
            window.webkit.messageHandlers.jsCallOc.postMessage("");
        }

        //有参数函数
        function testB(value) {
            window.webkit.messageHandlers.jsCallOc.postMessage("call oc");
        }

        function testC(value) {

            var finalObj = { "name": "chaman", "age": "18", "sex": "male" };
            window.webkit.messageHandlers.jsCallOc.postMessage(finalObj);
        }
    </script>

</body>

</html>

在控制器销毁的时候移除方法名

- (void)dealloc {
    [[_webView configuration].userContentController removeScriptMessageHandlerForName:@"jsCallOc"];
}
上一篇 下一篇

猜你喜欢

热点阅读