UIWebView与JS交互

2020-01-12  本文已影响0人  piggybear

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);

}

上一篇下一篇

猜你喜欢

热点阅读