js与OC互相调用 —— JavaScriptCore使用

在本系列交互文章中,第一篇的第二种方法已经简单介绍过使用的方式了,这里再单独拎出来补充以下细节。
(以下步骤,因为是把之前的文章补充以下,所以步骤大致相同,了解可跳过。)
1.html文件及编译环境配置


js与OC互相调用 —— JavaScriptCore使用_第1张图片
html文件.png

JavaScriptCore库的导入


js与OC互相调用 —— JavaScriptCore使用_第2张图片
导入框架.png
js与OC互相调用 —— JavaScriptCore使用_第3张图片
导入头文件.png

2.加载UIWebView
self.webView = [[UIWebView alloc] initWithFrame:self.view.frame];
    self.webView.delegate = self;
    NSURL *htmlURL = [[NSBundle mainBundle] URLForResource:@"index.html" withExtension:nil];
//    NSURL *htmlURL = [NSURL URLWithString:@"http://www.baidu.com"];
    NSURLRequest *request = [NSURLRequest requestWithURL:htmlURL];

在UIWebViewDelegate方法中,页面结束加载后开始进行交互操作

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    [self addCustomActions]; // UIWebview加载结束后开始进行交互
}

3.交互操作
JSContext是为JavaScript的执行提供运行环境,所有的JavaScript的执行都必须在JSContext环境中。JSContext也管理JSVirtualMachine中对象的生命周期。每一个JSValue对象都要强引用关联一个JSContext。当与某JSContext对象关联的所有JSValue释放后,JSContext也会被释放。

获取JSContext有多种方式,这里先使用这一种。

- (void)addCustomActions
{
    // 拿到context
    JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    
//    [context evaluateScript:@"var arr = [3, 4, 'abc'];"];

    [self addScanWithContext:context];
    
    [self addLocationWithContext:context];
    
    [self addSetBGColorWithContext:context];
    
    [self addShareWithContext:context];
    
    [self addPayActionWithContext:context];
    
    [self addShakeActionWithContext:context];
    
    [self addGoBackWithContext:context];
}

OC调用JS方法有多种。
方式一
使用JSContext的方法-evaluateScript,可以实现OC调用JS方法。

- (void)addShareWithContext:(JSContext *)context
{
    context[@"share"] = ^() {
        NSArray *args = [JSContext currentArguments]; // 获取参数列表
        
        if (args.count < 3) {
            return ;
        }
        NSString *title = [args[0] toString];
        NSString *content = [args[1] toString];
        NSString *url = [args[2] toString];
        // 在这里执行分享的操作
        
        // 将分享结果返回给js
        NSString *jsStr = [NSString stringWithFormat:@"shareResult('%@','%@','%@')",title,content,url];
//        使用[JSContext currentContext]而不是self.context来在block中使用JSContext,来防止循环引用。
        
        [[JSContext currentContext] evaluateScript:jsStr];
    };
}

方式二
使用JSValue的方法-callWithArguments,也可以实现OC调用JS方法。
示例

JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

[context[@"payResult"] callWithArguments:@[@"支付弹窗"]];

方法中实际使用,在执行原生OC方法之后,想要在OC执行完操作后,将结果回调给JS时。

- (void)addPayActionWithContext:(JSContext *)context
{
    context[@"payAction"] = ^() {
        NSArray *args = [JSContext currentArguments];
        
        if (args.count < 4) {
            return ;
        }
        
        NSString *orderNo = [args[0] toString];
        NSString *channel = [args[1] toString];
        long long amount = [[args[2] toNumber] longLongValue];
        NSString *subject = [args[3] toString];
        
        // 支付操作
        NSLog(@"orderNo:%@---channel:%@---amount:%lld---subject:%@",orderNo,channel,amount,subject);
        
        // 将支付结果返回给js
//        NSString *jsStr = [NSString stringWithFormat:@"payResult('%@')",@"支付成功"];
//        [[JSContext currentContext] evaluateScript:jsStr];
        [[JSContext currentContext][@"payResult"] callWithArguments:@[@"支付成功"]];
    };
}

关于JavaScriptCore的使用方法,简单介绍到这里。关于JavaScriptCore库的详细介绍,之后再整理。

你可能感兴趣的:(js与OC互相调用 —— JavaScriptCore使用)