美文网首页iOS开发
WKWebView与JS交互

WKWebView与JS交互

作者: Lxyang | 来源:发表于2018-11-13 15:44 被阅读32次

    前言

    经常看到安卓开发者前端联调,前端一句window.android.方法名(参数)这样的函数就调用了安卓方法,而ios确非常的麻烦,以前一般我们都是通过在- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(nonnull WKNavigationAction *)navigationAction decisionHandler:(nonnull void (^)(WKNavigationActionPolicy))decisionHandler中拦截url处理。现在,下面介绍另一种WKScriptMessageHandler方法实现,与安卓类似。


    ios端处理

    • 使用WKWebView,遵循WKScriptMessageHandler协议
    • 创建WKWebView
    // oc
    - (WKWebView *)wkWebView {
        if (!_wkWebView) {
            
            WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
            WKPreferences *preference = [[WKPreferences alloc] init];
            config.preferences = preference;
            
            _wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) configuration:config];
            
            _wkWebView.UIDelegate = self;
            _wkWebView.navigationDelegate = self;
        
        }
        return _wkWebView;
    }
    // swift
    // MARK: 懒加载
    lazy var webView: WKWebView = {
            
        let config = WKWebViewConfiguration.init()
        let preference = WKPreferences.init()
        preference.javaScriptCanOpenWindowsAutomatically = true
        config.preferences = preference
            
        let webV = WKWebView.init(frame: CGRect(x: 0, y:20, width: screenW, height: screenH-navH), configuration: config)
        webV.scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        webV.scrollView.scrollIndicatorInsets = webV.scrollView.contentInset
        webV.uiDelegate = self
        webV.navigationDelegate = self
        return webV
    }()
    
    • 注册监听与前端约好的方法名
    // oc
    - (void)viewWillAppear:(BOOL)animated {
        
        [super viewWillAppear:animated];
        
        [self.wkWebView.configuration.userContentController addScriptMessageHandler:self name:@"goHome"];
        [self.wkWebView.configuration.userContentController addScriptMessageHandler:self name:@"goLogin"];
        [self.wkWebView.configuration.userContentController addScriptMessageHandler:self name:@"buyLottery"];
        
    }
    // swift
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.webView.configuration.userContentController.add(self, name: "goHome")
        self.webView.configuration.userContentController.add(self, name: "goLogin")
        self.webView.configuration.userContentController.add(self, name: "buyLottery")
    }
    
    • 在页面消失时,记得移除监听
    //oc
    - (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
        [self.wkWebView.configuration.userContentController removeScriptMessageHandlerForName:@"goHome"];
        [self.wkWebView.configuration.userContentController removeScriptMessageHandlerForName:@"goLogin"];
        [self.wkWebView.configuration.userContentController removeScriptMessageHandlerForName:@"buyLottery"];
        self.wkWebView.UIDelegate = nil;
        self.wkWebView.navigationDelegate = nil;
    }
    
    //swift
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.webView.configuration.userContentController.removeScriptMessageHandler(forName: "goHome")
        self.webView.configuration.userContentController.removeScriptMessageHandler(forName: "goLogin")
        self.webView.configuration.userContentController.removeScriptMessageHandler(forName: "buyLottery")
        self.webView.uiDelegate = nil
        self.webView.navigationDelegate = nil
    }
    
    • 代理方法中监听前端调用原生的方法
    //oc
    /// 与js交互
    - (void)userContentController:(nonnull WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message {
        // 参数
        NSDictionary *body = message.body;
        // 约定好的函数名
        NSString *name = message.name;
    
        if ([name isEqualToString:@"goHome"]) {
            [self.navigationController popViewControllerAnimated:true];
        } else if ([name isEqualToString:@"goLogin"]) {
            [self.navigationController popViewControllerAnimated:true];
            [self.webObj.webViewEngine evaluateScript:@"window.location.href = \"login.html\";localStorage.clear();"];
        } else if ([name isEqualToString:@"buyLottery"]) {
            [[EUExPrintSdk sharedInstance] printBlueTooth:@[body]];
        }
    }
    // swift
    extension XMBaseWebVC: WKScriptMessageHandler {
    
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            
            let body = message.body as? [String:Any]
            let name = message.name
            XMLog(message: "messageHandler收到的名字为:"+name)
            switch name {
                case "goHome":
                    self.goHome()
                case "goLogin":
                    let url = body?["shareUrl"] as? String
                    let pasteBoard = UIPasteboard.general
                    pasteBoard.string = url
                    XMMessageHUD.showMessage(str: NSLocalizedString("复制成功", comment: ""), completion: nil)
                case "buyLottery":
                    let url = body?["url"] as? String
                    let title = body?["title"] as? String
                    let content = body?["description"] as? String
                    let pic = body?["pic"] as? String
                    XMLog(message: "........")
                default:
                    break
            }
        }
    }
    
    

    前端js调用

    注意:一定要参传数,不然原生是收不到消息
    如:

    window.webkit.messageHandlers.goHome.postMessage("哈哈"); // 回到首页操作
    window.webkit.messageHandlers.goLogin.postMessage("哈哈"); // 跳转到登录面
    window.webkit.messageHandlers.buyLottery.postMessage({"mount":"145","oderid":"6d-3891489374893473243","count":"12"}); // 执行买票操作,参数是通过json方法传送,原生是以body方式接收,接收到的是字典
    

    相关文章

      网友评论

        本文标题:WKWebView与JS交互

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