Swift 从零开始 12_Swift和H5的交互

本文主要讲述项目中用到的一套交互机制,方法很多,欢迎交流

首先,用的WkWebView

1
2
3
4
5
6
7
8
9
10
11
12
13
extension CBWebView: WKScriptMessageHandler {
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
guard let _handleViewController = handleViewController else { return }
//接受h5那边发过来的消息,消息存放在message的body中
guard let cmd = Cmd.create(with: message.body as! String) else { return }
CMDManager.sharedInstance.performCmd(_handleViewController, cmd: cmd)
}
}

cmd是自定义的存放消息的类

1
2
3
4
5
6
7
8
9
10
11
12
class Cmd {
class func create(with text: String) -> Cmd? {
if let json = JSON.createFromString(text) {
let cmd = Cmd()
cmd.action = json["cmd"].stringValue
cmd.params = json["data"]
return cmd
}
}

CMDManager是oc方法的管理类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class CMDManager: NSObject {
var currentCmdAction: String!
var currentCmdParams: JSON!
weak var currentViewController: UIViewController!
func performCmd(handleViewController: UIViewController, cmd: Cmd) {
currentCmdAction = cmd.action
currentViewController = handleViewController
currentCmdParams = cmd.params
if respondsToSelector(Selector(currentCmdAction)) {
performSelector(Selector(currentCmdAction))
DDLogVerbose("cmd: \(cmd.action), params: \(self.currentCmdParams.rawString() ?? "")")
} else {
DDLogWarn("\(cmd.action) has not be implement")
}
}
}
通过上面三段代码就可以知道:
h5发送消息到WKScriptMessageHandler的Message中,然后将消息体(message.body存到到cmd中,对应的action和params).然后再调用CMDManager的performCmd方法,将cmd传过来,然后通过respondsToSelector 方法判断该类中是否实现了对面方法(cmd.action),实现了就可以调用,没有实现则提示.

比如h5加载时,调用oc的hide_loading方法

通过h5的文档,知道方法名及参数,然后自己把方法实现即可.

这里是h5调用oc的方法,并且没有回调
1
2
3
4
5
//隐藏加载页面
func hide_loading () {
//调用CBWebView 的 hideLoadView()方法
(currentViewController as? FruitViewController )?.webView.hideLoadView()
}
下面说说h5调用oc方法之后,还要回调h5方法的例子
1
2
3
4
5
6
7
8
9
10
11
//获取app的数据
func get_app_data() {
//callbackName和callbackID是参数,通过cmd.params传过来的
let callbackName = self.currentCmdParams["callbackName"].stringValue
let callbackID = self.currentCmdParams["callbackID"].intValue
let loginInfo : LoginInfo
loginInfo = InfoManager.sharedInstance.readLoginInfo()!
//回调h5方法
(self.currentViewController as? FruitViewController)?.webView.getAppData(callbackName, callbackID: callbackID, loginInfo: loginInfo)
}

然后在CBWebView的Extension(新建一个类叫 WebViewExtension)中实现oc调用js的代码

1
2
3
4
5
//这是WkWebView种调用js方法的方法
private func perfromJs(method:String,param1:String,param2:String, completionHandler: ((Any?, NSError?) -> Void)?)
{
self.evaluateJavaScript("\(method)('\(param1)','\(param2)')", completionHandler: completionHandler)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//回调方法
//回调参数(callbackID,{uid:”10000”,”auth”:” asdasdasd213”})
func getAppData(callbackName: String, callbackID: Int,loginInfo: LoginInfo) {
var str1 = ""
var str2 = ""
str1 = "\(callbackID)"
str2 = "{\"uid\":\"\(loginInfo.uid)\",\"auth\":\"\(loginInfo.auth)\"}"
print("str------\(str1 + str2)")
perfromJs(callbackName, param1:str1, param2:str2) { (obj, err) in
print(err)
}
}
至此,swift中和h5的互调完成,整个逻辑其实很简单,主意和h5开发人员沟通好就行!