美文网首页
webviewTojs

webviewTojs

作者: alex_zn | 来源:发表于2018-07-19 14:34 被阅读0次

    要点

    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文件
    <button type="button" onclick="JS_Swift1()">JS调用Swift方法(无参)</button> </br>
    <button type="button" onclick="JS_Swift2()">JS调用Swift方法(传参)</button>
               
               <!--      模型注入     -->
               <b>model 注入</b>
               
               <div style="margin-top: 100px">
                   
                    <input type="button" value="Call ObjC system camera" onclick="OCModel.callSystemCamera()">
                    <input type="button" value="Call ObjC system alert" onclick="OCModel.showAlertMsg('js title', 'js message')">
                        
               </div>
               </hr>
               
               <div>
                   
                   <input type="button" value="Call ObjC func with JSON " onclick="OCModel.callWithDict({'name': 'testname', 'age': 10, 'height': 170})">
                       <input type="button" value="Call ObjC func with JSON and ObjC call js func to pass args." onclick="OCModel.jsCallObjcAndObjcCallJsWithDict({'name': 'testname', 'age': 10, 'height': 170})">
               </div>
               
               <div bgcolor="#ddd0">
                   <span id="jsParamFuncSpan" style="color: red; font-size: 50px;">interHtml</span>
               </div>
               
               <div bgcolor="#0000">
                   <img id="imgShowDiv" src="" width="300px" height="300px" style="display: block;" />
                </div>
               
               <script type="text/javascript">
                   
                   function jsFunc() {
                       alert('Objective-C call js to show alert');
                   }
               // 注意哦,如果JS写错,可能在OC调用JS方法时,都会出错哦。
               var jsParamFunc = function(argument) {
                   
                   document.getElementById('jsParamFuncSpan').innerHTML
                   = argument['name'];
               }

    相关文章

      网友评论

          本文标题:webviewTojs

          本文链接:https://www.haomeiwen.com/subject/ydltmftx.html