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

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


html文件.png

JavaScriptCore库的导入


导入框架.png
导入头文件.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库的详细介绍,之后再整理。

推荐阅读更多精彩内容

  • 本文由我们团队的 纠结伦 童鞋撰写。 写在前面 本篇文章是对我一次组内分享的整理,大部分图片都是直接从keynot...
    知识小集阅读 9,925评论 11 152
  • 随着H5技术的兴起,在iOS开发过程中,难免会遇到原生应用需要和H5页面交互的问题。其中会涉及方法调用及参数传值等...
    Chris_js阅读 1,221评论 1 7
  • 注:本文copy自http://www.jianshu.com/p/ac534f508fb0,纯属当笔记使用。 概...
    pi图阅读 362评论 1 3
  • 写在前面 本篇文章是对我一次组内分享的整理,大部分图片都是直接从keynote上截图下来的,本来有很多炫酷动效的,...
    _James_阅读 5,515评论 7 42
  • 周一晚上有幸参加了独立旅行爱好者Sothie的独家旅途直播分享,确实是受益匪浅! 我们都说想要一场说走就走的旅行,...
    秀秀秀Love阅读 44评论 0 2