美文网首页
IOS和JS交互那点事

IOS和JS交互那点事

作者: 夏天的橙子_ | 来源:发表于2017-08-05 12:00 被阅读31次

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

    跟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实现代码

    <input type="button" value="JS调用原生block实现" onclick="alert('alert');" />
    <input type="button" value="JS调用原生JSExport protocol实现" onclick="native.alert('alert');" />
    

    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 <JSExport>
    -(void)alert:(NSString *)alertText;
    @end
    
    @interface JSCallOCViewController : UIViewController<TestJSExport>
    @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交互那点事

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