UIWebView的js与native代码的交互

UIWebView 的 native交互


1. 实际开发中, 经常会通过前端webview来实现一些与native代码的交互功能,怎么实现呢?通常怎么做?有哪些实例枚举?

2. 这里说明一下常用方法有两种思路, 一个是直接使用JavaScriptCore框架,可以实现javascript和native代码的交互;还要一种思路是直接通过WebView的代理方法中添加代码或者解析URL来达到目的,本文介绍第二种。


一 、使用webview 怎样实现呢 ? 先介绍三个方法:(UIWebView的代理方法两个,UIWebView 提供的实例方法一个)

a. webview被触动加载之前会调用下面的代理。

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


b. webview加载完毕之后会调用的代理

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


c. 直接使用webview实例为自己的html文本 注入javascript代码 或者 调用javascript代码 都是用这个方法。

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



3. 直接上一块代码,简单演示怎样利用UIWebView的代理和实例方法实现 webview与native代码的交互。看看它们都是怎样运用的吧:

————

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


    /*通过js 方法执行获取webview的高度! */

    int h = [[webView stringByEvaluatingJavaScriptFromString:@"document.height"] floatValue];

    

    webView.userInteractionEnabled = h > self.height;

    webView.height = h;

    self.height = MAX(h, k_SpanLeft);

    

    /*取消长按webView上的链接弹出actionSheet的问题*/

    [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout = 'none';"];

    

    

    /*js方法遍历图片添加点击事件+返回图片个数*/

    static  NSString * const jsGetImages =

    @"function getImages(){\

    var objs = document.getElementsByTagName(\"img\");\

    for(var i=0;i<objs.length;i++){\

    objs[i].οnclick=function(){\

    document.location=\"myweb:imageClick:\"+this.src;\

    };\

    };\

    return objs.length;\

    };";

    [webView stringByEvaluatingJavaScriptFromString:jsGetImages];//注入js方法

    //注入自定义的js方法后别忘了调用 否则不会生效

    [webView stringByEvaluatingJavaScriptFromString:@"getImages()"];

    

}


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


    /// url的截获解析 通常在这个方法中获取url

    NSString *urlStr = request.URL.absoluteString;

    TBLog(@"%@",urlStr);

    if ([urlStr isEqualToString:@"about:blank"]) {

        return YES;

    }


    /* 解释一下,这个方法,每当用户触动webview上的空间,webview需要刷新的时候都会调用这个方法,返回值决定是否对页面进行刷新,上面通过@“about:blank”的校验,如果过是空白页,应当返回YES,让webview进行刷新。 余下情况看看是否需要返回NO吧?

     这里简单说明一下返回NO 的原因:

    1. 前提是这个界面第一遍加载的时候已经完成了所有视图的更新

    2. webview上空间的操作执行,会调用这个方法,但是界面不需要进行刷新(没有视图变化)

    3. 满足以上两个条件,然后这样做,减少了布标要的webview刷新操作,也实现了可能需要的拦截和阻断(主要是为了阻断后续的webViewDidFinishLoad方法执行)。

4. 这个拦截很多时候是有必要的,比如点击一个url,而这个url的目的不是用来加载,只是用来传递信息,这时候就应该拦截,然后做解析,如下:

    */

    return [self linkFromLinkUrl:request.URL];

    

    /*

     1.根据前面如果注入的获取网页界面图片的 javascript代码,那么点击图片的时候回触动下面方法的执行。

     2.下面方法的逻辑是 根据图片 路径 匹配本地数组中图片路径得到图片索引位置,关键还是前面给图片添加了点击事件在这里触发。

     */

    if ([urlStr hasPrefix:@"myweb:imageClick:"]) {

        NSString *imageUrl = [urlStr substringFromIndex:@"myweb:imageClick:".length];

        TBLog(@"image url------%@", imageUrl);

        for (int i=0; i<self.arrImgElement.count; i++) {

            TFHppleElement *tfhElement = self.arrImgElement[i];

            NSString *tempImgUrl = [tfhElement.attributes objectForKey:@"src"];

            if ([imageUrl isEqualToString:tempImgUrl]) {

                if ([self.delegate respondsToSelector:@selector(htmlViewEvent:withInfo:)]) {

                    [self.delegate htmlViewEvent:RichViewEventImgClick withInfo:[NSString stringWithFormat:@"%d",i]];

                }


                break;

            }

        }

        return NO;

    }

    

    

    return NO;

}


-(BOOL)linkFromLinkUrl:(NSURL *)linkUrl{

    NSString *url = linkUrl.absoluteString;

if(parse url     in order){

return NO;

} else if(parse url need link continue){

return YES;

}

    //如果是其他的超链接,启动safari进行跳转

    else (self.canOpenSafari) {

        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlStr]];

    }

    return NO;

}


结语:通过拦截URL解析和Javascript代码的注入执行,可以实现webview 到 native 的一个信息传递,但是能够感受到一定的局限性(如果我们想要传递一个son数据,使用url显然不是很方便,甚至因为url的规则限制而变成不可能)。这个可以通过JavaScriptCore框架来解决。另外添加javascript注入和调用javascript代码都使用唯一的一个函数stringByEvaluatingJavaScriptFromString进行动态添加(显然可以获取到所有html文本后字符串注入进去,但是麻烦会接踵而至的!),然而如果我们需要更多的javascript代码和native方法的交互性,动态性,和将更多权限交给前端代码而不是应用的native代码,那么这个法子显然也不是很方便,这个时候也需要考虑直接使用JavaScriptCore来解决了。

综合而言, 这些技巧可能很有用,局限是把最大权限交给了native代码。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值