原生运用中或多或少都会接入H5界面,运用WKWebView加载,这就避免不了native与H5交互了。

传统交互方案:

直接体系体系API。
长处:简略 缺陷:重复处理阻拦事情
举例:
想在H5加载之前就传递给H5一些参数信息,能够这么干:

        // 初始化WKWebView时候,直接传递给H5一点参数。  这儿以传给它平台信息为例。
        let configuration = WKWebViewConfiguration()
    configuration.applicationNameForUserAgent = "iOS"
    let script = WKUserScript(source: "window.platform = 'iOS'", injectionTime: .atDocumentStart, forMainFrameOnly: true)
    configuration.userContentController.addUserScript(script)

如果在加载界面后传递,运用evaluateJavaScript办法即可:

    // 这儿也能够添加参数
        let script = "window.webkit.messageHandlers.messageHandler.postMessage('Hello, H5!',{
     resolution: "#(resolution)",
     chartType: #(chartType)
    })"
    webView.evaluateJavaScript(script, completionHandler: nil)

添加交互事情:
configuration.userContentController.add(self, name: "MessageHandle")
然后再代理WKScriptMessageHandler办法里监听对应的事情即可:

  func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    switch message.name {
      case "MessageHandle": 
        print("处理H5数据")
      default: break
    }
  }

以上是运用体系API,基础通讯啦。可是这样,有多个事情,就要传多少次,很麻烦。 想这只监听一个办法,就能阻拦一切的交互事情呢?已经有了现成轮子,Swift运用WKWebViewJavascriptBridgeWKWebViewJavascriptBridge

依照步骤,只需两步,就可完成接入。

1、确保Bridge初始化前已经有了webView!!!
bridge = WKWebViewJavascriptBridge(webView: webView)
2、注册事情:

只需一致注册一个事情JS_CALL_APP_FUN来监听即可。

  1. // JS主动调用native的办法
  2. // 这是JS会调用JS_CALL_APP_FUN办法,这是native注册给JS调用的
  3. // JS需求回调,当然JS也能够传参数过来。data便是JS所传的参数,不一定需求传=
  4. // native端通过responseCallback回调JS端,JS就能够得到所需求的数据
    jsBridge.register(handlerName: "JS_CALL_APP_FUN", handler: { parameters, responseCallBack in
      // 解析处理JS调OC的事情,然后将结果callback回来给他
      JSWebManager.appResponeJsCallBack(params: parameters, callBack: responseCallBack)
    })

native 调用JS办法。 也只注册一个事情APP_CALL_JS_FUN. 具体什么事情、以及参数,在data里传给JS.

jsBridge.callHandler:"APP_CALL_JS_FUN" data:@"传递给 JS 的参数") { responseData in
    }

具体后续办法名啊、参数啊, 就与JS与约定好了。这样就能一致处理了。 不想写了,直接上我的部分代码自己看看吧。
恳求传参:

{
'operate':'callPhone',
'data':{
        'phone':'18888888888'//手机号码,必须
    }
}

回来给JS数据:

{
'msg':'',//success或许为其他Native或许传给H5的错误提示信息
'code':0,//0 代表Native解析成功
'data':{
        'token':'fewifhwiuhfuiewhf'
    }
}

一致阻拦处理办法:

先界说传递以及恳求的Model:

/// 与H5交互,H5调用OC的办法传过来的Model
struct ExWebRequestModel<T: Codable>: Codable {
  var operate: String = ""// 具体办法称号
  var data: T
}
// data里单个参数的
struct ExWebRequestCommonModel: Codable {
  var params: String?
  var token: String?
    ...
}
struct ExWebRequestParamModel: Codable {
  var params: ExWebParamsModel?
  var path: String?
    ...
}
/// 如果有带额定参数,放在这儿
struct ExWebParamsModel: Codable {
  var isbn: String?
  var studentId: String?
    ...
}
/// OC处理完成后回来给H5回来的Model
struct ExWebResponseModel: Codable {
  var code: Int = 0
  var msg: String = "sucess"
  var data: ExWebResponDetailModel?
}
// 一切的回来数据都放在一个Model里,要哪个给哪个就行
struct ExamWebResponDetailModel: Codable {
  var client: String?
  var version: String?
  var model: String? //手机类型
  var appVersionName: String?
  var appVersionCode: String? //版本号
  var manufacturer: String? //手机厂商
  var debug: Bool?
  var name: String?
  var userType: String?
  var status: Int?
    ...
}

一致阻拦处理Manager:

static func appResponeJsCallBack(params: [String: Any]?, callBack: ((_ responseData: Any?) -> Void)?) {
    guard let paramsDict = params else { return }
    guard let operate = paramsDict["operate"] else { return }
   
    let operateType = JSCallAppFuncName(rawValue: operate as! String)
    switch operateType {
            // 这个长处特别,独自处理
      case .openPage:
        do {
          let jsonData = try JSONSerialization.data(withJSONObject: paramsDict, options: .prettyPrinted)
          let paramsModel = try App.shared.decoder.decode(ExWebRequestModel<ExWebRequestParamModel>.self, from: jsonData)
          // 处理具体的JS调OC事情
          operateJsCallFunc(commonModel: ExWebRequestCommonModel(), paramsModel: paramsModel.data, operate: operateType ?? .none, callBack: callBack)
        } catch {
          print("Error: (error)")
        }
      default:
        do {
          let jsonData = try JSONSerialization.data(withJSONObject: paramsDict, options: .prettyPrinted)
          // 处理 data
          //      let jsonString = String(data: jsonData, encoding: .utf8)
          let model = try App.shared.decoder.decode(ExWebRequestModel<ExWebRequestCommonModel>.self, from: jsonData)
          print(model.operate)
          // 处理具体的JS调OC事情
          operateJsCallFunc(commonModel: model.data, paramsModel: ExamWebRequestParamModel(), operate: operateType ?? .none, callBack: callBack)
        } catch {
          print("Error: (error)")
        }
    }
  }
 
  /// 解析JS掉用的哪个办法
  static func operateJsCallFunc(commonModel: ExWebRequestCommonModel, paramsModel: ExWebRequestParamModel, operate: JSCallAppFuncName, callBack: ((_ responseData: Any?) -> Void)?) {
    switch operate {
      case .getClientInfo:
        // 对应事情处理完成后,回来数据给JS
        let model = ExWebResponseModel(data: ExamWebResponDetailModel(client: "iOS", version: Env.osVersion, model: UIDevice.current.type.rawValue, appVersionName: Env.appName, appVersionCode: Env.bundleShortVersion, manufacturer: "iPhone", debug: Env.isDebug))
        jsCallFuncCallback(model: model, callBack: callBack)
      case .openPage:
        let paramsModel = paramsModel.path
        // 拿到参数知道干啥事哈
       
        // 回参数给JS
        let model = ExamWebResponseModel()
        jsCallFuncCallback(model: model, callBack: callBack)
      case .getUserInfo:
        let model = ExamWebResponseModel(data: ExamWebResponDetailModel(name: "小红", userType: "iOS客户端"))
        jsCallFuncCallback(model: model, callBack: callBack)
                ...
      default:
        break
    }
  }
 
 
  /// JS调用完成给它的回调信息- 具体哪个Model不同罢了
  static func jsCallFuncCallback(model: ExWebResponseModel, callBack: ((_ responseData: Any?) -> Void)?) {
    do {
      let jsonData = try App.shared.encoder.encode(model)
      let jsonString = String(data: jsonData, encoding: .utf8)
      callBack?(jsonString)
    } catch {
      print("Error: (error)")
    }
  }
}

算了先这样吧,看不懂的再来。。