javaScriptCore 实战与小结

 

源码在这,看不懂的直接撸源码就行,转载声明出处

  • 原生调用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)
        }
    }

到这里基本上完成了,有不足的地方欢迎指正。


原文地址:https://www.cnblogs.com/L-vincen/p/6641203.html