iOS开发-使用JavaScriptCore框架处理UIWebV

2019-03-07  本文已影响0人  来者可追文过饰非

首先看下JS部分的代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>

    <script>
        // 如果是使用UIWebView的话,使用这个测试调起原生暴露的方法
        function callIosMethod() {
            // log();
            // logString('这个是传进来的字符串');
            logWithCallBack('这是一个带回调的传进的字符串', function(params0,param1) {
                var str = params0 + param1;
                alert(str);
            });
        }
        // WKWebView
        function callWKMethod() {
             // 注意,logWithCallBack为原生暴露的方法名,必须要与原生代码中的对应
             // 参数部分可以通过postMessage的参数传递
             window.webkit.messageHandlers.logWithCallBack.postMessage({"key" : "value", "callback" : "111"});
        }
        // 供原生调用的测试方法(理论来说,只要是在这里写的public方法,都算是暴露出来的方法,都可以调用)
        function exportToIos() {
            alert('iOS调起了JS方法');
        }

        function exportToIosWithArguement(arguement) {
            alert(arguement);
        }

        function methodWithThreeArguements(arg1, arg2) {
            alert(arg1 + arg2);
        }
    </script>

    <style>
    p {
        background-color: #ff3333;
        color: #fff;
        padding: 10px, 10px;
        display: inline-block;
    }
    </style>
</head>
<body>
    <p onclick="callIosMethod()">我是个按钮</p>
    <p onclick="callWKMethod()">测试WKWebView点这个<p/>
</body>
</html>

UIWebView部分代码

- (void)viewDidLoad {
    [super viewDidLoad];
    // 此处我的webView为xib拖得,省去了初始化webView的代码

    // 加载本地html文件
    NSString *path = @"/Users/liuxu/Desktop/H5学习代码/index.html";
    NSURL *url = [NSURL fileURLWithPath:path];
    [self.webView loadRequest:[NSURLRequest requestWithURL:url]];
    
    self.webView.delegate = self;
    
    // 获取当前webview的JSContext
    self.jsContext = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    // 暴露方法供H5调用 
    // 无参数
    self.jsContext[@"log"] = ^(){
        NSLog(@"hahhahahhaha");
    };
    // 一个参数
    self.jsContext[@"logString"] = ^(NSString *str) {
        NSLog(@"%@",str);
    };
    // 有回调
    self.jsContext[@"logWithCallBack"] = ^(NSString *str, JSValue *value) {
        NSLog(@"%@",str);
        [value callWithArguments:@[@"1",@"2"]];
    };
}
// 调用JS的方法
- (IBAction)callJS:(id)sender {
    // 设置异常处理,此步骤不能省略
    [self.jsContext setExceptionHandler:^(JSContext *context, JSValue *exception) {
       
    }];
    // 无参数
//    [self.jsContext evaluateScript:@"exportToIos()"];
    // 有参数
    [self.jsContext evaluateScript:@"exportToIosWithArguement('lalala')"];
}

效果图如下

1.点击页面上的'callJS'按钮 点击页面上的CallJS按钮.png

2.点击H5页面上的'我是个按钮',控制台输出'这是一个带回调的传进的字符串',随后触发回调部分的代码


点击我是个按钮.png

WKWebView部分代码

#import "WKWebViewController.h"
#import <WebKit/WebKit.h>
#import <JavaScriptCore/JavaScriptCore.h>
@interface WKWebViewController () <WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler>
@property (strong, nonatomic)  WKWebView *webView;
@end

@implementation WKWebViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    WKUserContentController *userContentController = [[WKUserContentController alloc] init];
    // 注入方法
    [userContentController addScriptMessageHandler:self name:@"log"];
    [userContentController addScriptMessageHandler:self name:@"logString"];
    [userContentController addScriptMessageHandler:self name:@"logWithCallBack"];
    configuration.userContentController = userContentController;
    
    self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:configuration];
    self.webView.UIDelegate = self;
    self.webView.navigationDelegate = self;
    [self.view insertSubview:self.webView atIndex:0];
    
    NSString *path = @"/Users/liuxu/Desktop/H5学习代码/index.html";
    NSURL *url = [NSURL fileURLWithPath:path];
    [self.webView loadRequest:[NSURLRequest requestWithURL:url]];
}

// 调用JS暴露出的方法
- (IBAction)callJS:(id)sender {
    NSString *js = @"exportToIos()";
    [self.webView evaluateJavaScript:js completionHandler:nil];
}

// 用于拦截alert方法,实现该方法后可以js可以正常调用alert方法
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}

// JS调用原生注入的方法后会走该方法,可以在此处判断并进行相应操作
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    NSDictionary *dict = message.body;
    if ([message.name isEqualToString:@"log"]) {
        
    }
    else if ([message.name isEqualToString:@"logString"]) {
        
    } else if ([message.name isEqualToString:@"logStringWithCallBack"]) {
        
    }
}

- (void)dealloc {
    [self.webView.configuration.userContentController removeAllUserScripts];
}

@end
上一篇 下一篇

猜你喜欢

热点阅读