美文网首页
native与JS简单交互

native与JS简单交互

作者: Fsn_soul | 来源:发表于2017-03-24 13:06 被阅读147次

native调用JS方法.

使用UIWebView- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;方法,就可以调用JS的方法了.

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    //JS返回的一般是一个json字符串.
    NSString *infoJsonStr = [webView stringByEvaluatingJavaScriptFromString:@"getShareInfo();"];
    if(infoJsonStr.length > 0)
    {
        //将json字符串解析为OC字典.
       NSDictionary *infoDict = [NSJSONSerialization JSONObjectWithData:[infoJsonStr dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
        ...
    }
}

JS调用native方法.

点击网页上的某个按钮,想要执行native的某个方法.

比如,网页上有一个分享按钮,点击后弹出分享平台选择view,但这个view及弹出动画都是native这边实现的.所以此时JS需要调用native方法,并将分享内容参数传给native.

思路:给JS中的元素桥接一个native的对象或函数.这样点击网页上的分享按钮时,就可以执行native的方法了.

上面的思路如何实现呢?
系统已经为我们提供了相关API,那就是OC的JSContext类的类别SubscriptSupport提供的方法
- (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key;
Use this method (or Objective-C subscript syntax) to bridge native objects or functions for use in JavaScript.
object参数通常是一个block对象.上述方法也可以使用下标语法:context[@"xxx"] = ^{};

当webView加载完成后,在该代理方法里实现.

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    //获取webView的JS环境(每个页面都有自己的JSContext)
    self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    //打印JS运行时候的异常
    self.context.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue){
        context.exception = exceptionValue;
        NSLog(@"%@", exceptionValue);
    };
    
    //给JS元素关联一个native实现.该block里可以获取JS传来的参数.注意:如果block内部用到JSContext,可以使用[JScontext currentContext]获取当前的context,防止循环引用.也可以使用weakSelf,都是一样的效果.
    __weak typeof(self) weakSelf = self;
    void(^shareParameterBlock)() = ^{
        __strong typeof(self) strongSelf = weakSelf;
        if (strongSelf == nil) {
            return ;
        }
        //获取参数.当JS参数不固定时,可以通过以下方法获取参数.
        NSArray *args = [JSContext currentArguments];
        JSValue *jsValue = [args firstObject];
        
        NSDictionary *objDict = [jsValue toDictionary];
        NSLog(@"objDict = %@", objDict);
        
        if (objDict)
        {
            dispatch_async(dispatch_get_main_queue(), ^{
                [strongSelf share:objDict]; //native的-share:方法
            });
        }
    };
    //进行桥接
    [self.context setObject:[shareParameterBlock copy] forKeyedSubscript:@"share"];
}

这样当用户点击js上的分享按钮时,就可以弹出本地的分享选择视图了.

由于不太懂HTML5和JavaScript,所以上面有些地方的表述可能并不恰当.

相关文章

网友评论

      本文标题:native与JS简单交互

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