IOS和JS交互那点事

很早之前有个项目牵扯到这块就很想写篇博客记录下这篇文章了,这阵子有个项目又刚好遇到,正好有空,记录记录。

跟web的同鞋打过交道的肯定都知道,只要是涉及双端交互就两种方案啦。

  • 截取链接,一般也就通过UIWebView回调代理shouldStartLoadWithRequest截取固定链接然后在原生里面做相应的业务操作,实现也比较简单,当然这个方案也是一般涉及业务简单时候可以用,比如给个固定链接跳转原生界面,如果业务复杂点web要给原生传递参数或者多个参数再或者原生要操作web里面的相关业务,那就得考虑下面的方案二了。

  • JS交互,iOS7以前我们对JS的操作只有webview里面一个函数 stringByEvaluatingJavaScriptFromString,当然也有很多人是用的这个第三方JavascriptBridge,IOS7之后,苹果可能也考虑到了这方面的需求,也很给力推出了JavaScriptCore这个框架。

通过stringByEvaluatingJavaScriptFromString 实现OC执行JS代码

stringByEvaluatingJavaScriptFromString 这个方法是UIWebView里面的方法,也是最为简单的和JS交互的方式。

-(nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;

用法比较简单,一般在代理方法- (void)webViewDidFinishLoad:(UIWebView*)webView中使用。

- (void)webViewDidFinishLoad:(UIWebView*)webView
{
    // 获取当前页面的title
    NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
    // 获取当前页面的url
    NSString *url = [webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];
}

JavaScriptCore

这是IOS7后苹果推出了JavaScriptCore这个框架,让原生和web界面交互非常方便了。代码是开源的JavaScriptCore 可以下载下来看看。

我们先了解下里面常见的属性和协议

  • JSContext:给JavaScript提供运行的上下文环境,通过-evaluateScript:方法就可以执行一JS代码。
  • JSValue:JavaScript和Objective-C数据和方法的桥梁,封装了JS与ObjC中的对应的类型,以及调用JS的API等。
  • JSManagedValue:管理数据和方法的类JSVirtualMachine:处理线程相关,使用较少。
  • JSExport:这是一个协议,如果JS对象想直接调用OC对象里面的方法和属性,那么这个OC对象只要实现这个JSExport协议就可以了。

OC调JS


    self.context = [[JSContext alloc] init];

    [self.context evaluateScript:@"function reduce(a,b) {return a-b}"];

    JSValue *value = [self.context[@"reduce"] callWithArguments:@[@10, @3]];

    NSLog(@"---%@", @([value toInt32]));    //---7

JS调OC

JS调用OC有两个方法:block和JSExport protocol。

html实现代码



oc实现代码

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

    // 打印JS异常
    self.context.exceptionHandler =
    ^(JSContext *context, JSValue *exceptionValue)
    {
        context.exception = exceptionValue;
        NSLog(@"%@", exceptionValue);
    };

    // 以 block 形式关联 JavaScript function
    self.context[@"alert"] =
    ^(NSString *alertText)
    {
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:alertText message:nil delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil, nil];
        [alert show];
    };
    
    // 以 JSExport 协议关联 native 的方法
    self.context[@"native"] = self;
}

当前类需要声明和实现JSExport协议

@protocol TestJSExport 
-(void)alert:(NSString *)alertText;
@end

@interface JSCallOCViewController : UIViewController
@property (strong, nonatomic) JSContext *context;
@end

#pragma mark - JSExport Methods
-(void)alert:(NSString *)alertText
{
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:alertText message:nil delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil, nil];
    [alert show];
}

好啦,关于JavaScriptCore的基本介绍就是这样了。
参考http://www.jianshu.com/p/a329cd4a67ee

你可能感兴趣的:(IOS和JS交互那点事)