webviewTojs

要点

native -> js
主要是通过 直接 执行一段 js 函数代码

1,context.evaluateScript("SwiftFunc()")//异步

2, webView.stringByEvaluatingJavaScriptFromString("SwiftFunc()")//同步

//同步

js -> native

1.通过context?.setObject(unsafeBitCast(temp, to: AnyObject.self), forKeyedSubscript: "test2" as (NSCopying & NSObjectProtocol)!)

2,通过新建model后 通过 setObject注入model, 而model要实现protocol,protocol是要 执行的方法。 在js中onclick 中 实现 model.func()

swift文件

  // Swift 调用JS 方法 (无参数)
    @IBAction func swift_js_pargram(_ sender: AnyObject) {
        
        _ = self.context?.evaluateScript("Swift_JS1()")
//        self.webView.stringByEvaluatingJavaScriptFromString("Swift_JS1()") // 此方法也可行
    }
    
    // Swift 调用JS 方法 (有参数)
    @IBAction func swift_js_nopargam(_ sender: AnyObject) {
        
        _ = self.context?.evaluateScript("Swift_JS2('oc' ,'Swift')")
//        self.webView.stringByEvaluatingJavaScriptFromString("Swift_JS2('oc','swift')") // 此方法也可行
    }
    
    func menthod1() {
        print("JS调用了无参数swift方法")
    }
    
    func menthod2(_ str1: String, str2: String) {
        print("JS调用了有参数swift方法:参数为\(str1),\(str2)")
    }
    
    func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
        print(error)
    }
    
}

extension ViewController: UIWebViewDelegate {
    
    func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        
        return true
    }
    
    func webViewDidStartLoad(_ webView: UIWebView) {
        
        print("webViewDidStartLoad----")
        
    }
    
    func webViewDidFinishLoad(_ webView: UIWebView) {
        
        print("webViewDidFinishLoad----")
        self.context = webView.value(forKeyPath: "documentView.webView.mainFrame.javaScriptContext") as? JSContext
        
        // JS调用了无参数swift方法
        let temp1: @convention(block) () ->() = {
            
            self.menthod1()
        }
        
        self.context?.setObject(unsafeBitCast(temp1, to: AnyObject.self), forKeyedSubscript: "showAlart1" as (NSCopying & NSObjectProtocol)!)
        
        // JS调用了有参数swift方法
        let temp2: @convention(block) () ->() = {
            
            let array = JSContext.currentArguments() // 这里接到的array中的内容是JSValue类型
            
            for object in array! {
                print(object)
            }
            
            self.menthod2((array?[0] as AnyObject).toString(), str2: (array?[1] as AnyObject).toString())
        }
        
        self.context?.setObject(unsafeBitCast(temp2, to: AnyObject.self), forKeyedSubscript: "test2" as (NSCopying & NSObjectProtocol)!)
        
        // 模型注入的方法
        let model = JSObjCModel()
        model.controller = self
        model.jsContext = context
        
        // 这一步是将OCModel这个模型注入到JS中,在JS就可以通过OCModel调用我们暴露的方法了。
        context?.setObject(model, forKeyedSubscript: "OCModel" as (NSCopying & NSObjectProtocol)!)
        

    }
}

@objc protocol JavaScriptSwiftDelegate: JSExport {
    func callSystemCamera()
    
    func showAlert(_ title: String, msg: String)
    
    func callWithDict(_ dict: [String: AnyObject])
    
    func jsCallObjcAndObjcCallJsWithDict(_ dict: [String: AnyObject])
}

@objc class JSObjCModel: NSObject, JavaScriptSwiftDelegate ,UIImagePickerControllerDelegate,UIActionSheetDelegate,UINavigationControllerDelegate {
    
    weak var controller: UIViewController?
    weak var jsContext: JSContext?
    
    func callSystemCamera() {
        
        print(controller.debugDescription)
        
        let imagePickerController:UIImagePickerController = UIImagePickerController()
        imagePickerController.delegate = self
        
        imagePickerController.allowsEditing = true//true为拍照、选择完进入图片编辑模式
        imagePickerController.sourceType = .camera

        
        controller?.present(imagePickerController, animated: true, completion: nil)
//        let jsFunc = self.jsContext?.objectForKeyedSubscript("jsFunc");
//        _ = jsFunc?.call(withArguments: []);
    }
    
    func showAlert(_ title: String, msg: String) {
        
        DispatchQueue.main.async { () -> Void in
            let alert = UIAlertController(title: title, message: msg, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "ok", style: .default, handler: nil))
            self.controller?.present(alert, animated: true, completion: nil)
        }
    }
    
    // JS调用了我们的方法
    func callWithDict(_ dict: [String : AnyObject]) {
        print("js call objc method: callWithDict, args: %@", dict)
    }
    
    // JS调用了我们的又去
    func jsCallObjcAndObjcCallJsWithDict(_ dict: [String : AnyObject]) {
        print("js call objc method: jsCallObjcAndObjcCallJsWithDict, args: %@", dict)
        
//        let jsParamFunc = self.jsContext?.objectForKeyedSubscript("jsParamFunc");
//        let dict = NSDictionary(dictionary: ["age": 18, "height": 168, "name": "lili"])
//        
//        _ = jsParamFunc?.call(withArguments: [dict])
//        
//        _ = JSContext.currentArguments()
        

        let url = Bundle.main.url(forResource: "rc_ac_audio_file_icon.png", withExtension: nil)
        let data = NSData.init(contentsOf: url!)
        
        let jsPar = jsContext?.objectForKeyedSubscript("showImgFunc");
//        let argument = image as? NSData ?? NSData()
        
        _ = jsPar?.call(withArguments: [data!])
        
    }
    
    //
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        
//        let image = info[UIImagePickerControllerEditedImage] //as? UIImage ?? UIImage()
//        
//        let jsPar = jsContext?.objectForKeyedSubscript("jsParamFunc");
//        let argument = image as? NSData ?? NSData()
//        
//        _ = jsPar?.call(withArguments: [argument])
//        
        
    }
html文件
 
model 注入
interHtml

你可能感兴趣的:(webviewTojs)