美文网首页
iOS webView和h5交互

iOS webView和h5交互

作者: 大树和小鱼 | 来源:发表于2021-12-08 11:14 被阅读0次

最近对接过公司的一个h5的东西,就是给一个入口,点击进wkWebView,其他的交给h5,简单说一下方法思路

第一 和h5共同商讨交互字段问题,定下来返回格式。然后使用wkwebView的configuration配置一下

let userContent = WKUserContentController()
self.userContent = userContent
userContent.add(JFToNative(), name: "JsToNative")
config.userContentController = userContent
let webView = CustomWKWebView(frame: view.bounds, configuration: config)

其中 userContent.add(JFToNative(), name: "JsToNative")

JFToNative() 就是实现 WKScriptMessageHandler 协议的 func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) () 方法

class JFToNative: NSObject, WKScriptMessageHandler {
    weak var webView: WKWebView!
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        webView = message.webView
        if let dict = message.body as? [String: Any] {
            debugPrint(dict)
            if let tempClass = dict["class"] as? String {
                let method = dict["method"] as? String ?? ""
                let json = JSON(dict["params"] as Any)
                if tempClass == "xxx" {
                //这里调用你的方法
                }else if tempClass == "xxx" {
                  //这里调用你的方法
                }
            }
        }
    }

你也可以在当前类实现,直接self即可,但是我学习大佬同事的方式,把它分开写了,但是由于东施效颦,没学好(在第一步的时候和h5商定协议就有问题,大佬的方式是 window.webkit.messageHandlers.JsToNative.postMessage({'class' : 'NativeXxx', 'method' : 'xxx', 'params' : {'key0' : 'value0', 'key1' : 'value1', ...}})

在桥接文件这么写

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        guard let dict = message.body as? [String : Any],
        let cls = NSClassFromString(kNameSpace + "." + (dict["class"] as? String ?? "")) as? NativeBase.Type,
        let method = dict["method"] as? String, !method.isEmpty else {return}
        
        let obj = cls.init()
        let sel = Selector(method + ":")
        if obj.responds(to: sel) {
            obj.webView = message.webView
            var params = dict["params"] as? [String : Any]
            if params?.count == 0 {
                params = nil
            }
            obj.perform(sel, with: params)
        }
    }

他的class继承 NativeBase

class NativeBase: NSObject {
    weak var webView: WKWebView?
    
    override required init() {
        super.init()
    }
}   

class就是你方法调用应该写的类名字,我们提供,method就是h5的回掉方法名字,params就是提供给我们的一些参数。

我商定的交互方式是class 是方法名,所以造成了无法像大佬这种用,不能继承他的基础webVC。只能拷贝他的webVC删除多余的方法。使用了重复的代码。

言归正传,我们给js发消息是通过evaluateJavaScript这个方法

open func evaluateJavaScript(_ javaScriptString: String) async throws -> Any    

javaScriptString是一个字符串,一般和h5商定好,给他返回某种格式的json字符串。我们商定的是 如下格式

dic = ["code": "000000", "msg": msg]
if let data = try? JSONSerialization.data(withJSONObject: dic, options: .prettyPrinted) {
                if let str = String(data: data, encoding: .utf8) {
                    let strs = str.jsonRemoveOther()
                  
                  

jsonRemoveOther是

///jsonstr移除其他特殊字符
    func jsonRemoveOther() -> String {
        
        var content = self.replacingOccurrences(of: "\\'", with: "\"")
        content = content.replacingOccurrences(of: "\r", with: "")
        content = content.replacingOccurrences(of: "\n", with: "")
        content = content.replacingOccurrences(of: "\t", with: "")
        content = content.replacingOccurrences(of: "\\", with: "")
        return content
    }
    

有些时候需要把iOS的特殊符号移除掉,不然h5解析不到,这方面我不是特别清楚,应该h5是可以处理的,但是具体看沟通吧。

其他问题,我们的h5 VC 导航栏是给h5自己设置的。出现一个问题,h5VC的滚动范围,可以滚动到状态栏去,但是这个听其他同事们说,之前接过的h5是都是让h5自己处理的,所以这个问题我让他们来处理,起始我自己的话,把view的y轴位置增加一个状态栏的高度,view 的height 减少一个h5的高度。但是这个页面其他地方也有用,所以有点害怕出问题。所以给h5处理了

相关文章

网友评论

      本文标题:iOS webView和h5交互

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