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,这样咱们才能够判断用户的行为。html

同时在咱们的项目开发过程当中,其实咱们有的时候也但愿去操控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 来调用对应的方法。以下:html5

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

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

现在不少网页都是采用html5来编写,随着phoneGap的推出,在移动开发中也有一些应用采用html5来开发,开源项目Cordova的推出,让咱们能够在移动web页面中直接调用咱们native的方法。web

集成以下(采用cocoapods环境下):apache

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

vim Podfile
在Podfile中添加以下代码数组

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

pod updateapp

而后咱们从Cordova开源项目中将config.xml文件拷贝到项目中。并配置该文件,因为在web端是经过ide

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

相关文章
相关标签/搜索