源码在这,看不懂的直接撸源码就行,转载声明出处
- 原生调用JS的大致流程,做了个思维简图

这是代码流程
// JS数据 func getJSVar() { let context: JSContext = JSContext() //定义JS环境 let result1: JSValue = context.evaluateScript("1 + 1") //执行JS代码 print(result1) // 输出2 // 定义js变量和函数 context.evaluateScript("function sum(param1, param2) { return param1 + param2; }") //通过下标来获取js方法并调用方法 let pp_func = context.objectForKeyedSubscript("sum") let result = pp_func?.call(withArguments: [10,10]).toString() print(result!) //输出20 //下标获取js数组的值 context.evaluateScript("var names = ['vincen1', 'vincen2', 'vincen3']") let names = context.objectForKeyedSubscript("names") let name = names?.objectAtIndexedSubscript(0).toString() print(name ?? "空值处理") //输出 Grace }
- 重点是JS调用原生,看流程图

闭包绑定用的不多,这里就不做阐述,有兴趣的自己去看
这里只说JSExport协议方法
声明一个类,用来处理协议方法
import UIKit import JavaScriptCore @objc protocol swiftDelegate : JSExport { func wxPay(_ orderNo: String) //这里的方法与JS调用名相同 func wxShare(_ dict: [String : AnyObject]) func showDMessage(_ dict1:[String : String], _ dict2 : String) // js调用App的功能后 App再调用js函数执行回调 func callHandler(_ handleFuncName: String) } @objc class javaScriptModel: NSObject ,swiftDelegate { weak var controller: UIViewController? weak var jsContext: JSContext? func wxPay(_ orderNo: String) { // print("订单号:", orderNo) showDialog("", message: "获取到订单号(orderNo),调用微信支付") // 调起微信支付逻辑 } func showDMessage(_ dict1: [String : String], _ dict2: String) { showDialog("", message:"我是第一个字典(dict1)-----我是第二个字符串(dict2)") } func wxShare(_ dict: [String : AnyObject]) { showDialog("", message: "获取到分享的字典(dict),调用微信支付") } func callHandler(_ handleFuncName: String) { let jshandFunc = jsContext?.objectForKeyedSubscript("(handleFuncName)") let dict = ["name" : "pp"] as [String : Any] jshandFunc?.call(withArguments: [dict]) } func showDialog(_ title: String, message: String) { let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default, handler: nil)) controller?.present(alert, animated: true, completion: nil) } }
然后在VC中的webview中代理方法中注入模型
//webview代理中,绑定原生协议方法 func webViewDidFinishLoad(_ webView: UIWebView) { pp_jsContext = webView.value(forKeyPath: "documentView.webView.mainFrame.javaScriptContext") as! JSContext let model = javaScriptModel() model.controller = self model.jsContext = pp_jsContext // 这一步是将SwiftJavaScriptModel模型注入到JS中,在JS就可以通过WebViewJSBridge调用我们暴露的方法了。 pp_jsContext.setObject(model, forKeyedSubscript: "WebViewJSBridge" as (NSCopying & NSObjectProtocol)!) // pp_jsContext.exceptionHandler = { (context, exception) in //打印异常 print("exception:", exception) } }
到这里基本上完成了,有不足的地方欢迎指正。