在平常的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