zoukankan      html  css  js  c++  java
  • UIWebView和Js交互


    在日常的ios项目开发中,我们经常会在原生应用中嵌入web页面,通常我们只是进行一个展示,没有其它的一些功能。但是也有一些项目中需要web页面中的html和native进行交互。但是ios sdk 并没有相应的方法来让我们做到js代码来和原生进行交互。但是webview在加载前会调用其一个delegate方法,通过监听

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

    代理方法,我们可以通过url的变化来判断用户目前的一些点击行为。如下:

    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    if ([[request.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]hasSuffix:@"login_app"]) {
    //用户点击了登录按钮
    [self doLogin];
    return YES;
    }else if([[request.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]hasSuffix:@"register_app"]){
    //用户点击了注册按钮
    [self doRegister];
    return YES;
    }
    }

    我们可以看到,针对不同的url,我们可以判断对应的用户行为,但是前提是用户的不同行为给webView带来不同的响应url,这样我们才可以判断用户的行为。

    同时在我们的项目开发过程中,其实我们有的时候也希望去操控webview中显示的页面。针对这一点,ios sdk 提供了相应的方法,

    - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
    比如我们想获取页面中的id为icon_app的某个属性。我们可以如下操作

    NSString *downLoadPath = [webView stringByEvaluatingJavaScriptFromString:@"document.getElementById('icon_app').getAttribute('data_url')"];

    在编写这种代码的前提是我们对于js比较熟悉,能给书写一些简单的js代码,当然我们也可以向相应同事提供帮助。另外其实我们也可以调用webView中js方法,前提是我们的前端同事把对应的js方法写好,然后在我们在native中采用stringByEvaluatingJavaScriptFromString 来调用对应的方法。如下:

    [myWebView stringByEvaluatingJavaScriptFromString:@"showPlay()"];

    直接调用相应的方法名字。

    如今很多网页都是采用html5来编写,随着phoneGap的推出,在移动开发中也有一些应用采用html5来开发,开源项目Cordova的推出,让我们可以在移动web页面中直接调用我们native的方法。

    集成如下(采用cocoapods环境下):

    1.在podfile中添加Cordova的应用,如下

    vim Podfile
    在Podfile中添加如下代码

    pod 'Cordova', '3.4.0'
    保存后,执行如下代码

    pod update

    然后我们从Cordova开源项目中将config.xml文件拷贝到项目中。并配置该文件,由于在web端是通过

    exec(<successFunction>, <failFunction>, <service>, <action>, [<args>]);
    来调用native方法,所以在我们本地是需要建立一个 service Class,按照Cordova官方文档的说法这个类需要继承于CDVPlugin类,需要引用Cordova中某个类,我们只需要添加如下引用头文件

    #import "CDV.h"
    新建类如下:

    #import "CDV.h"

    @protocol HJMVPluginDelegate;
    @interface HJMVPlugin : CDVPlugin

    + (instancetype)sharedPlugin;
    - (void)addDelegate:(id)deleget;
    - (void)discussHtmlReplyWith:(CDVInvokedUrlCommand*)command;//详情页面中的回复方法
    - (void)gotoDiscussDetailWith:(CDVInvokedUrlCommand*)command;//列表页面中跳转详情页面;

    @end


    @protocol HJMVPluginDelegate <NSObject>
    @optional
    - (void)discussHtmlShouldReplyWithArguments:(NSArray*)arguments;
    - (void)shouldGotoDiscussDetailWithArguments:(NSArray*)arguments;
    @end

    这个类里面定义的两个方法就是我们exec(<successFunction>, <failFunction>, <service>, <action>, [<args>]);方法中的<action>。command是由webview这边传过来的一些参数,在native方法中都是可以取出来加以运用。

    那我们现在可以来配config.xml文件了,在config中插入如下代码:

    <feature name="HJMVPlugin">
    <param name="ios-package" value="CDVLocalStorage"/>
    </feature>

    feature的name属性应该为我们定义的service class 的classname,param对应的name属性为ios-package不可以改变的。
    这样web页面就可以调用我们原声应用的相应的方法,我们来看看被调用的原生应用的方法中做了哪些处理:

    - (void)discussHtmlReplyWith:(CDVInvokedUrlCommand*)command{
    //http://cordova.apache.org/docs/en/3.4.0/guide_platforms_ios_plugin.md.html#iOS%20Plugins
    [self.delegates enumerateObjectsUsingBlock:^(id<HJMVPluginDelegate> delegate, BOOL *stop) {
    if([delegate respondsToSelector:@selector(discussHtmlShouldReplyWithArguments:)]){
    [delegate discussHtmlShouldReplyWithArguments:command.arguments];
    }
    }];
    }
    在被调用的方法中我们可以通过command.arguments来取出web页面给我们传过来的数组,其对应exec(<successFunction>, <failFunction>, <service>, <action>, [<args>]);中的[<args>],参数的顺序需要web端和native协调tongyi好。

     一下是注意点:

    1.在使用cordova的时候是不可以调用UIWebView,而是需要继承cordova的CDVViewController,在CDVViewController中是内嵌了一个webview,是有这个webview来加载我们的web页面,在这里我们只需给CDVViewController设置startPage属性就好。

    2.目前这方面的开源项目还不是太多,所以需要多次尝试,在这个过程中遇到一些问题也是必然,所以也别沮丧,当然我们也可以参考官方网站上的文档https://cordova.apache.org/。

    以上这些方法都是可以实现的,都是基于我项目中的一些情况来写的这篇文章。

    杭州ios交流群 372471379

  • 相关阅读:
    Codeforces 1045C Hyperspace Highways (看题解) 圆方树
    Codeforces 316E3 线段树 + 斐波那切数列 (看题解)
    Codeforces 803G Periodic RMQ Problem 线段树
    Codeforces 420D Cup Trick 平衡树
    Codeforces 295E Yaroslav and Points 线段树
    Codeforces 196E Opening Portals MST (看题解)
    Codeforces 653F Paper task SA
    Codeforces 542A Place Your Ad Here
    python基础 异常与返回
    mongodb 删除
  • 原文地址:https://www.cnblogs.com/xishui2011/p/3698884.html
Copyright © 2011-2022 走看看