美文网首页
iOS-WKWebview与JS交互

iOS-WKWebview与JS交互

作者: 翀鹰精灵 | 来源:发表于2021-12-07 14:47 被阅读0次
    在APP开发中,调用H5极验功能涉及到原生与JS 交互,我用的是系统原生的方式实现,下面记录下实现步骤。

    (仅涉及iOS端工作流程记录)

    【OC版本:】
    
    @interface ViewController ()<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>
    @property(nonatomic, strong)WKWebView *webView;
    @end
    
    @implementation ViewController
    
    -(WKWebView *)webView {
        if (_webView == nil) {
            //创建网页配置对象
            WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
            // 创建设置对象
            WKPreferences *preference = [[WKPreferences alloc]init];
            //设置是否支持 javaScript 默认是支持的
            preference.javaScriptEnabled = YES;
            // 在 iOS 上默认为 NO,表示是否允许不经过用户交互由 javaScript 自动打开窗口
            preference.javaScriptCanOpenWindowsAutomatically = YES;
            config.preferences = preference;
            //这个类主要用来做 native 与 JavaScript 的交互管理
            WKUserContentController * wkUController = [[WKUserContentController alloc] init];
            //注册一个 name 为 jsToOcNoPrams 的 js 方法 设置处理接收 JS 方法的对象
            [wkUController addScriptMessageHandler:self name:@"jsToOcNoPrams"];
            [wkUController addScriptMessageHandler:self name:@"jsToOcWithPrams"];
            config.userContentController = wkUController;
            //用于进行 JavaScript 注入
            WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:@"jsBridge" injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
            [config.userContentController addUserScript:wkUScript];
            _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) configuration:config];
            // UI 代理
            _webView.UIDelegate = self;
            // 导航代理
            _webView.navigationDelegate = self;
            //此处即需要渲染的网页
            NSString *path = @"http://xxxxx-xxx.com/hnatravel/signcodeIOS.html";
            NSURL *url = [NSURL URLWithString:path];
            NSURLRequest *request = [NSURLRequest requestWithURL:url];
            //NSString *htmlString = [[NSString alloc]initWithContentsOfFile:url encoding:NSUTF8StringEncoding error:nil];
            //[_webView loadHTMLString:htmlString baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
            [_webView loadRequest:request];
            
        } return _webView;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        [self.view addSubview:self.webView];
    }
    
    #pragma mark <WKScriptMessageHandler>
    -(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
        //此处 message.body 即传给客户端的 json 数据
        //用 message.body 获得 JS 传出的参数体
        NSDictionary * parameter = message.body;
        //JS 调用 OC
        if([message.name isEqualToString:@"jsToOcWithPrams"]){
            //在此处客户端得到 js 透传数据 并对数据进行后续操作
           NSString *params = parameter[@"params"];
           NSString *result = parameter[@"result"];
           NSLog(@"params:%@ , result:%@",params,result);
        }
    }
    
    
    【Swift版本:】
    class GT3WKWebView: UIView {
        private lazy var webView: WKWebView = {
            //创建网页配置对象
            let config = WKWebViewConfiguration()
            // 创建设置对象
            let preference = WKPreferences()
            //设置是否支持 javaScript 默认是支持的
            preference.javaScriptEnabled = true
            // 在 iOS 上默认为 NO,表示是否允许不经过用户交互由 javaScript 自动打开窗口
            preference.javaScriptCanOpenWindowsAutomatically = true
            config.preferences = preference
            //这个类主要用来做 native 与 JavaScript 的交互管理
            let wkUController = WKUserContentController()
            //注册一个 name 为 jsToOcNoPrams 的 js 方法 设置处理接收 JS 方法的对象
            wkUController.add(self, name: "jsToOcNoPrams")
            wkUController.add(self, name: "jsToOcWithPrams")
            config.userContentController = wkUController
            //用于进行 JavaScript 注入
            let jSString = "jsBridge"
            let wkUScript = WKUserScript(source: jSString, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
            config.userContentController.addUserScript(wkUScript)
            webView = WKWebView(frame: CGRect(x: 20, y: 0, width: self.frame.size.width - 40, height: 280), configuration: config)
            webView.center = self.center
            webView.isOpaque = false
            webView.backgroundColor = UIColor.clear
            webView.scrollView.showsVerticalScrollIndicator = false
            webView.scrollView.showsHorizontalScrollIndicator = false
            // UI 代理
            webView.uiDelegate = self
            // 导航代理
            webView.navigationDelegate = self
            //此处即需要渲染的网页
            let url = "http://xxxxx-xxx.com/hnatravel/signcodeIOS.html"
            if let url1 = URL(string: url) {
                webView.load(URLRequest(url: url1))
            }
            return webView
        }()
      
        override init(frame: CGRect) {
            super.init(frame: frame)
            self.addSubview(webView)
        }
    }
    
    extension GT3WKWebView : WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler {
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            // 此处 message.body 即传给客户端的 json 数据
            //用 message.body 获得 JS 传出的参数体
            let parameter = message.body as? [String:String]
            //JS 调用 OC
            if message.name == "jsToOcWithPrams" {
                //在此处客户端得到 js 透传数据 并对数据进行后续操作
                let params =  parameter?["params"] ?? ""
                let result =  parameter?["result"] ?? "0"
            
            }
        }
    }
    

    运行效果如下图所示:

    image.png

    当滑块验证成功/失败的时候,会触发wkwebview的代理方法,如下所示:

    image.png

    此时,通过wkwebview的回调,我们就可以拿到H5传给我们的数据信息了,可以根据数据做对应逻辑处理。

    Demo下载地址

    END.

    相关文章

      网友评论

          本文标题:iOS-WKWebview与JS交互

          本文链接:https://www.haomeiwen.com/subject/kzvoxrtx.html