美文网首页
H5与Native的爱恨纠缠

H5与Native的爱恨纠缠

作者: 往事不许提 | 来源:发表于2019-04-30 16:40 被阅读0次

    随着移动互联网进入下半场,App开发也不再局限与Native开发,或多或少都要用到H5技术,完全以H5技术来构建App的框架也越来越多,比较有代表性的React Native、Flutter。
    在这个发展过程中,Native与H5擦出些小火花是不可避免的,接下来就来聊聊他们之间的你来我往、爱恨纠缠!

    OC调用JS

    • 不需要JavaScriptCore.framework框架
    [self.webview stringByEvaluatingJavaScriptFromString:@"js代码字符串"];
    
    • 需要JavaScriptCore.framework框架
      三个重要的角色:JSContext、JSValue、JSExport。
      JSContext:创建js的上下文,提供js的运行环境;
      JSValue:JavaScript和Objective-C数据和方法的桥梁 ,封装了JS与Objc中的对应的类型,以及调用JS的API 等;
      JSExport: 这是一个协议,采用协议的方法进行交互的时候,自己定义的协议必须遵守此协议;
    JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    NSString *jsString = @"JS中的函数名('参数1','参数2')";
    [context evaluateScript:jsString];
    

    JS调用OC

    1.协议

    @protocol  协议名称 <JSExport>
    协议方法一
    - (void)methodFirst;
    协议方法二
    - (void)methodSecond;
    @end 
    
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        // 获取上下文
       self.jsContext  = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
       self.jsContext[@"delegate"] = self;
       self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue){
           context.exception = exceptionValue;
           NSLog(@"异常信息:%@",exceptionValue);
       };
    }
    
    - (void)methodFirst {
       //方法实现
       ......
       // 获得想要的结果把结果传回给JS
       //获取JS中的函数
       JSValue *callBack1 = self.jsContext[@"JS中函数名"];
       //把前面获取到的结果作为参数传进JS的callBack参数中
       [callBack1 callWithArguments:@[参数1,参数2,...]];
    }
    - (void)methodSecond {
       //方法实现
       ......
       // 获得想要的结果把结果传回给JS
       //获取JS中的函数
       JSValue *callBack2 = self.jsContext[@"JS中函数名"];
       //把前面获取到的结果作为参数传进JS的callBack参数中
       [callBack2 callWithArguments:@[参数1,参数2,...]];
    }
    
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    </head>
    <body>
    <div style="margin-top: 20px">
    <h2>JS与OC交互</h2>
    <input type="button" value="JS直接调用OC方法 methodFirst" onclick="delegate.methodFirst()">
    </div>
    <div>
    <input type="button" value="JS直接调用OC方法 methodFirst" onclick="callSecondMethod()">
    </div>
    <script>
      var callSecondMethod  = function() {
            //参数
            var callInfo = JSON.stringify({"key":"value"});
            delegate.methodSecond();// 有参数就传参,无参数就空
      }
      
      var CallBack  = function (str) {
          alert(str);
      }
       var alertCallBack = function(str) {
           alert(str);
       }
    </script>
    

    2.block

      self.jsContext  = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
      self.jsContext[@"约定函数名"] = ^(){
            // 获取到的调用“约定方法名”时传递的参数数组
            NSArry *args = [JSContext currentArguments];
            for(JSValue *jsVal in args){
                  NSLog(@"%@",jsVal.toString);
            }
    
            __block JSContext *contextObject = context;
            dispatch_async(dispatch_get_main_queue(), ^{
                 UI操作
                 NSString *jsStr = @"js函数名('传递返回值')";
                 [contextObjet ealuateScript:jsStr];
            });
      }
    

    以上就是全部内容。
    今天利用以上技术点写了一个H5调用系统相册的小插件,详情:【Demo】(https://github.com/UnclenamedJack/js-oc)

    相关文章

      网友评论

          本文标题:H5与Native的爱恨纠缠

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