美文网首页iOS 程序员
iOS中OC和JS的互调

iOS中OC和JS的互调

作者: 湮灭_尘事 | 来源:发表于2016-07-22 10:57 被阅读200次

    首先我们要考虑到iOS中OC和JS相互交互的方案:
    一、WebView的代理:
    在大部分的app中直接使用,可以在WebView的代理方法中,通过拦截的方式与native进行交互,通常是通过拦截url scheme判断是否是我们需要拦截处理的url及其所对应的要处理的功能是什么。任意版本都支持。
    二、JavaScriptCore:
    需在iOS7之后就出现了JavaScriptCore.framework来用于和JS进行交互,但是它不支持iOS6,那么对于还需要支持iOS6的APP来说,就可以暂时不用考虑了。
    三、WebViewJavascriptBridge:
    我们也可以使用WebViewJavascriptBridge开源库,它的本质也是通过webview的代理拦截scheme,然后再注入相应的JS代码的。

    **UIWebView:
    **

    **1、OC直接调用JS **
    ①网页加载完成时调用的代理方法
    ②当网页加载完成之后,通过OC的方法调用JS的代码,删除网页展示时不需要的内容
    ③OC调用JS的代码还可以给网页中的标签添加点击事件或者给网页添加标签

    -(void)webViewDidFinishLoad:(UIWebView *)webView;
    

    ④网页加载完成之后,OC方法调用JS代码

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

    删除前的图片:


    **—————————————————————————————————————
    **
    **————————————————————————————————————— **

    以下是OC调用JS代码的具体实现:

    [代码]objc代码:

    - (void)webViewDidFinishLoad:(UIWebView *)webView
    {
        // JS的代码
        NSMutableString *JSStM = [NSMutableString string];
         
        /**
         ①找到要删除的对应的标签:var headerTag = document.getElementsByTagName('header')[0];
         ②找到要删除的标签对应的父节点:headerTag.parentNode
         ③从父节点中将要删除的标签移除:headerTag.parentNode.removeChild(headerTag);
         */
        // 删除导航
        [JSStM appendString:@"var headerTag = document.getElementsByTagName('header')[0];headerTag.parentNode.removeChild(headerTag);"];
         
        // 删除中间的“立即购买”按钮
        [JSStM appendString:@"var buyTag = document.getElementsByClassName('buy-now')[0];buyTag.parentNode.removeChild(buyTag);"];
         
        // 删除底部"APP下单返积分抵现金”悬停按钮
        [JSStM appendString:@"var footerBtnTag = document.getElementsByClassName('footer-btn-fix')[0]; footerBtnTag.parentNode.removeChild(footerBtnTag);"];
         
        // 删除底部“各种信息”布局
        [JSStM appendString:@"var footerTag = document.getElementsByClassName('footer')[0]; footerTag.parentNode.removeChild(footerTag);"];
         
        // 给标签“顶部的图片”添加点击事件
        /**
         ①JS中给标签添加相应的事件:弹框
         var figureTag = document.getElementsByTagName('figure')[0].children[0];figureTag.onclick = function(){alert("点我点我点我")};
         ②通过点击某个标签跳转到其他链接:给图片添加点击事件
         var figureTag = document.getElementsByTagName('figure')[0].children[0];figureTag.onclick = function(){window.location.href = 'http://www.baidu.com'};
          
         跳转到百度中的OC调用JS代码
         [JSStM appendString:@"var figureTag = document.getElementsByTagName('figure')[0].children[0];figureTag.onclick = function(){window.location.href = 'http://www.baidu.com'};"];
        */
        // 通过自定义协议头的方式来实现控制器间的跳转,即JS调用OC代码
    //    [JSStM appendString:@"var figureTag = document.getElementsByTagName('figure')[0].children[0]; figureTag.onclick = function(){window.location.href = 'xg://?src= '+this.src};"];
        // 也可写成一下代码
        [JSStM appendString:@"var figureTag = document.getElementsByTagName('figure')[0].children[0]; figureTag.onclick = function(){window.location.href = 'xg://www.hahah.com'};"];
         
        // OC调用JS代码
        [webView stringByEvaluatingJavaScriptFromString:JSStM];  
    }
    

    **执行以上代码后,删掉框框中的内容后的图片:
    **
    **
    **

    **—————————————————————————————————————
    **
    —————————————————————————————————————

    **2、接下来就是JS来调用OC的代码了:
    **
    ①拦截WebView上的所有的网络请求 ②JS和OC进行交互的渠道

    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
    

    ③给顶部的图片添加点击事件,使标签可以被点击,让其返回到第一个界面

    [代码]objc代码:

    // 通过自定义协议头的方式来实现控制器间的跳转,即JS调用OC代码
    
         
    [JSStM appendString:
    @"var figureTag = document.getElementsByTagName('figure')[0].children[0]; figureTag.onclick = function(){window.location.href = 'xg://?src= '+this.src};"
    ];
    
        
    // 也可写成一下代码
    
        
    [JSStM appendString:
    @"var figureTag = document.getElementsByTagName('figure')[0].children[0]; figureTag.onclick = function(){window.location.href = 'xg://www.hahah.com'};"
    ];
    

    ④点击事件发送网络请求的目的 : 可以拦截到标签的点击事件;自定义协议的目的 : 是为了给事件添加一个特殊的标记,如果拦截到请求,就可以通过这个特殊的标记来区分要做的事情

    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest*)requestnavigationType:(UIWebViewNavigationType)navigationType
    
    {NSLog(@"%@",request.URL.absoluteString);
    // 拿到网页上的请求地址
    NSString*URLString = request.URL.absoluteString;
    // 判断网页的请求地址协议是否是我们自定义的那个
    
        
    NSRange range = [URLString rangeOfString:@"xg://?src="];
    
    //    if (range.length > 0) {
    if([URLString isEqualToString:@"xg://www.hahah.com"]){             
    NSLog(@"你点击的是图片");      
    // 控制器的跳转    
    [self .navigationController popToRootViewControllerAnimated: YES];
    
            
    // 拦截到的这个自定义协议的请求时,我是不需要做网页加载的,就返回NO.
    
            
    return NO;        
    /**        
    温馨提醒:       
    ①这里点击标签之后,如果不需要加载任何的网页,就需要return NO;        
    ②如果需求是 : 点击网页的分享图标(按钮),跳转到分享页面,业务逻辑跟点击图片实现跳转是一样的,只需要在网页中找到那个分享的标签,确定他的点击事件并发送一个自定义协议头的请求,然后拦截这个特殊协议头的请求即可         
    */   
    }   
    return YES
    ;
    }
    


    **—————————————————————————————————————
    **
    —————————————————————————————————————

    相关文章

      网友评论

        本文标题:iOS中OC和JS的互调

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