美文网首页
UIWebView与JS交互

UIWebView与JS交互

作者: piggybear | 来源:发表于2020-01-12 19:26 被阅读0次

    js调用oc方法

    第一种

    html代码

    <!DOCTYPE html>
    <html>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport">
    
    <body style="background-color: white;">
        <script type="text/javascript">
            function buttonClick() {
                var ocReturnValue = ocFunction("参数1", "参数2")
                document.getElementById('result').innerText = "result: " + ocReturnValue;
            }
        </script>
        <button type="button1" onclick="jsCallNative1()" style="width:100%; height:50px;" />调用OC代码 无参数 无返回值</button>
        <div style="width:100%; height:30px;"></div>
        <button type="button2" onclick="jsCallNative2('我是参数1', '我是参数2')" style="width:100%; height:50px;" />调用OC代码 有参数
        无返回值</button>
        <div style="width:100%; height:30px;"></div>
        <button type="button3" onclick="buttonClick()" style="width:100%; height:50px;" />调用OC代码 有参数 有返回值</button>
        <br />
        <p id="result">返回值:</p>
    </body>
    </html>
    

    ios代码

    #pragma mark - UIWebViewDelegate
    
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        JSContext *jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
        jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception) {
            NSLog(@"出现异常,异常信息:%@",exception);
        };
     
        jsContext[@"jsCallNative1"] = ^(){
            NSLog(@"调用成功 button1");
        };
        
        jsContext[@"jsCallNative2"] = ^(){
            NSArray *currentParamers = [JSContext currentArguments];
            dispatch_async(dispatch_get_main_queue(), ^{
                //js调起OC代码,代码在子线程,更新OC中的UI,需要回到主线程
            });
            for (NSString *content in currentParamers) {
                NSLog(@"传过来的参数是 %@",content);
            }
        };
        
        jsContext[@"ocFunction"] = ^(){
            NSArray *currentParamers = [JSContext currentArguments];
            for (NSString *content in currentParamers) {
                NSLog(@"传过来的参数是 %@",content);
            }
            //避免循环引用
            JSContext *context = [JSContext currentContext];
            return [JSValue valueWithObject:@"我是函数返回值" inContext: context];
        };
    
    }
    

    第二种

    html代码

    <!DOCTYPE html>
    <html>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport">
    
    <body style="background-color: white;">
        <script type="text/javascript">
            function buttonClick() {
                var ocReturnValue = NativeObject.ocFunction("参数")
                document.getElementById('result').innerText = "result: " + ocReturnValue;
            }
        </script>
        <button type="button1" onclick="NativeObject.jsCallNative1()" style="width:100%; height:50px;" />调用OC代码 无参数 无返回值</button>
        <div style="width:100%; height:30px;"></div>
        <button type="button2" onclick="NativeObject.jsCallNative2('我是参数')" style="width:100%; height:50px;" />调用OC代码 有参数
        无返回值</button>
        <div style="width:100%; height:30px;"></div>
        <button type="button3" onclick="buttonClick()" style="width:100%; height:50px;" />调用OC代码 有参数 有返回值</button>
        <br />
        <p id="result">返回值:</p>
    </body>
    </html>
    

    ios代码

    JSObjectDelegate.h 文件

    #import <Foundation/Foundation.h>
    #import <JavaScriptCore/JavaScriptCore.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @protocol JSObjectDelegate <JSExport>
    
    -(void)jsCallNative1;
    - (void)jsCallNative2:(NSString *)parameter;
    -(NSString *)ocFunction:(NSString *)parameter;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    
    #pragma mark - UIWebViewDelegate
    
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        JSContext *jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
        jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception) {
            NSLog(@"出现异常,异常信息:%@",exception);
        };
    
        //写法1
        //此方法会转换self为JS对象,但是self中必须实现指定的方法 定义一个协议遵守JSExport,然后定义js对应的方法传递给js
        JSValue * jsCallNative = [JSValue valueWithObject:self inContext: jsContext];
        jsContext[@"NativeObject"] = jsCallNative;
        //写法2
        //self.jsContext[@"NativeObject"] = self;
        //注:写法1和写法2效果相同,推荐写法1,毕竟系统方法
    }
    
    #pragma mark - 供JavaScript调用的方法
    
    - (void)jsCallNative1 {
        JSValue *currentThis = [JSContext currentThis];
        JSValue *currentCallee = [JSContext currentCallee];
        NSLog(@"currentThis1 is %@",[currentThis toString]);
        NSLog(@"currentCallee1 is %@",[currentCallee toString]);
        
    }
    
    - (void)jsCallNative2:(NSString *)parameter {
        NSArray *currentParamers = [JSContext currentArguments];
        dispatch_async(dispatch_get_main_queue(), ^{
            //js调起OC代码,代码在子线程,更新OC中的UI,需要回到主线程
            NSLog(@"parameter:%@", parameter);
        });
        NSLog(@"currentParamers %@",currentParamers);
    }
    
    - (NSString *)ocFunction:(NSString *)parameter {
        NSArray *currentParamers = [JSContext currentArguments];
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"parameter:%@", parameter);
        });
        NSLog(@"currentParamers %@",currentParamers);
        return [NSString stringWithFormat:@"我是函数返回值 %@", parameter];
    }
    

    oc调用js方法

    第一种

    html代码

    <!DOCTYPE html>
    <html>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport">
    
    <body style="background-color: white;">
        <script type="text/javascript">
            var nativeCallJS = function(parameter) {
                document.getElementById('result').innerText = "result: " + parameter;
            };
        </script>
        <br />
        <p id="result">oc调用js传参数:</p>
    </body>
    </html>
    

    ios代码

    #pragma mark - UIWebViewDelegate
    
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        JSContext *jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
        jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception) {
            NSLog(@"出现异常,异常信息:%@",exception);
        };
    
       //oc调用js
        JSValue * nativeCallJS = jsContext[@"nativeCallJS"];
        [nativeCallJS callWithArguments:@[@"hello word"]];
    }
    

    第二种

    html代码

    <!DOCTYPE html>
    <html>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport">
    
    <body style="background-color: white;">
        <script type="text/javascript">
            globalObject = new Object();
            globalObject.nativeCallJS = function (parameter) {
                document.getElementById('result').innerText = "result: " + parameter;
            };
        </script>
        <br />
        <p id="result">oc调用js传参数:</p>
    </body>
    </html>
    

    ios代码

    #pragma mark - UIWebViewDelegate
    
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        JSContext *jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
        jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception) {
            NSLog(@"出现异常,异常信息:%@",exception);
        };
    
        //拿到js中要调用方法的全局对象
        JSValue * jsObj = jsContext[@"globalObject"];
        //jsObj执行其方法nativeCallJS
        JSValue * returnValue = [jsObj invokeMethod:@"nativeCallJS" withArguments:@[@"hello word"]];
       //调用了js中方法"nativeCallJS",并且传参数@"hello word",这里returnValue是调用之后的返回值,可能为nil
        NSLog(@"returnValue:%@",returnValue);
    
    }
    
    

    相关文章

      网友评论

          本文标题:UIWebView与JS交互

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