iOS,WKWebView加载HTML与JS交互。

由于项目使用到了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)];

    //设置代理用来获取加载状态等等信息...
    _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代码。




    
    walletProj


    


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];
   //需要实现,可同时注册多个方法名字,但是记得在控制器销毁时候移除。
    [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];
    //设置代理用来获取加载状态等等信息...
    _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(<数据>))


    
    walletProj



    





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

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

你可能感兴趣的:(iOS,WKWebView加载HTML与JS交互。)