你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS原生App與H5頁面交互 離線緩存 筆記

iOS原生App與H5頁面交互 離線緩存 筆記

編輯:IOS開發綜合
//webview每次加載之前都會調用這個方法,利用該代理方法截取JS的href來調用原生的方法

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

       然而這次的交互要求是進行雙向通信,即JS調用原生App的方法之後,原生App要講相關參數信息返回給H5頁面,H5頁面接受到參數信息後做其他處理。

例:H5頁面的發布信息按鈕,在點擊按鈕後要在原生端判斷用戶是否登錄,若沒有登錄則彈出原生登錄頁面,登錄成功後將用戶信息返回給H5頁面,繼續發布流程。

重點來了!
在這裡推薦一個比較好的第三方庫即:WebViewJavascriptBridge 

地址:https://github.com/marcuswestin/WebViewJavascriptBridge

通過使用該庫可以輕松實現JS與原生交互。

//初始化WebViewJavascriptBridge方法

_bridge= [WebViewJavascriptBridge bridgeForWebView:self.BookWebView webViewDelegate:self handler:^(id data,WVJBResponseCallback responseCallback) {

}];

//原生與JS約定接口名為“testObjcCallback”,data是JS傳遞過來的信息,responseCallback來將信息傳遞給JS

[_bridge registerHandler:@"testObjcCallback" handler:^(id  data,WVJBResponseCallback responseCallback) {

responseCallback("postInfomationToJS")

}];

WebViewJavascriptBridge使用說明(IOS)

由於現在很多產品都是有安卓版跟ios版,就意味著同一樣東西要出兩套,由兩組人去完成,不僅增加了開發成本,也大大加劇了維護成本。聰明的coder想出了跨平台的思路,用html寫頁面,分別用webview(ios),(安卓)來加載,對某些html無法調用的硬件,通過雙方的交互來實現方法的互調和傳值。這個過程就是跨平台。
下面來說一下WebViewJavascriptBridge在ios端怎麼樣使用。
首先確保一份已經配好功能的html文件。(html還在學習階段,暫時就不賣弄了。。。)

1.初始化一個webview(viewdidload)

UIWebView* webView = [[UIWebView alloc] initWithFrame:self.view.bounds];  
[self.view addSubview:webView]; 

2.將此webview與WebViewJavascriptBridge關聯(viewdidload)

if (_bridge) { return; }  

[WebViewJavascriptBridge enableLogging];  

_bridge = [WebViewJavascriptBridge bridgeForWebView:webView webViewDelegate:self handler:^(id data, WVJBResponseCallback responseCallback) {  
    NSLog(@"ObjC received message from JS: %@", data);  

    responseCallback(@"Response for message from ObjC");  
}]; 

ps:此時你的webview就與js搭上橋了。下面就是方法的互調和參數的互傳。

(1) js調oc方法(可以通過data給oc方法傳值,使用responseCallback將值再返回給js)

[_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) {  
     NSLog(@"testObjcCallback called: %@", data);  
     responseCallback(@"Response from testObjcCallback");  
 }]; 

這裡注意testObjcCallback這個方法的標示。html那邊的命名要跟ios這邊相同,才能調到這個方法。當然這個名字可以兩邊商量著自定義。簡單明確即可。

(2)oc調js方法(通過data可以傳值,通過response可以接受js那邊的返回值)

id data = @{ @"greetingFromObjC": @"Hi there, JS!" };  
 [_bridge callHandler:@"testJavascriptHandler" data:data responseCallback:^(id response) {  
     NSLog(@"testJavascriptHandler responded: %@", response);  
 }];  

注意這裡的testJavascriptHandler也是個方法標示。
(3)oc給js傳值(通過response接受返回值)

[_bridge send:@”A string sent from ObjC to JS” responseCallback:^(id response) {
NSLog(@”sendMessage got response: %@”, response);
}];

(4)oc給js傳值(無返回值)

[_bridge send:@”A string sent from ObjC after Webview has loaded.”];

##2 UIWebView頁面信息的離線緩存

推薦一個比較好的第三方庫RNCachingURLProtocol ,只需要在AppDelegate中加入下面方法即可。
[NSURLProtocolregisterClass:[RNCachingURLProtocolclass]];
地址:https://github.com/rnapier/RNCachingURLProtocol


##3  NSURLConnection小解

NSURLConnection提供對網絡異步加載請求的支持,並且將獲取的數據返回給代理。提供了簡單的接口去創建和取消連接,同時使用delegate方法去支持連接過程的反饋和控制 。在實際開發中直接用的不多,但是有的第三方庫卻是用它來封裝的。

舉例一: 
1、先創建一個NSURL 
2、在通過NSURL創建NSURLRequest,可以指定緩存規則和超時時間 
3、創建NSURLConnection實例,指定NSURLRequest和一個delegate對象 
   如果創建失敗,則會返回nil,如果創建成功則創建一個NSMutalbeData的實例用來存儲數據 

代碼: 

NSURL *url = [NSURL URLWithString:@”http://192.168.2.128:9090/ssonew/login/UserLogin.action?name=mql&psd=123456“];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
self.theConncetion = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES];

if (_theConncetion) {
    self.receiveData = [[NSMutableData alloc]init];
}
NSURLConnection有3個初始化函數,只有第一個初始化函數可以做到創建連接但是並 
不馬上開始下載,而是通過start:開始,調用該初始化函數時,startImmediately傳NO
(id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately NS_AVAILABLE(10_5, 2_0); (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate; (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate;

當收到initWithRequest: delegate:或收到connectionWithRequest: delegate: 消息時,下載會立即開始,在代理(delegate)
收到connectionDidFinishLoading:或者connection:didFailWithError:消息之前 
可以通過給連接發送一個cancel:消息來中斷下載 

connection: willSendRequest: redirectResponse:這個方法在請求將要被發送出去之前會調用
返回值是一個NSURLRequest,就是那個真正將要被發送的請求

第二個參數request就是被重定向處理過後的請求
第三個參數response是觸發重定向請求的響應包.默認是支持跳轉的。

(NSURLRequest )connection:(NSURLConnection )connection willSendRequest:(NSURLRequest )request redirectResponse:(NSURLResponse )response
{
NSURLRequest *newRequest = request;
if (response) {
NSLog(@”redirect!!!”); //如,請求google的網站時會有跳轉發生
newRequest = nil; //拒絕跳轉
}

return newRequest;
}


當服務器提供了足夠客戶程序創建NSURLResponse對象的信息時,代理對象會收到 
一個connection:didReceiveResponse:消息,在消息內可以檢查NSURLResponse 
對象和確定數據的預期長途,mime類型,文件名以及其他服務器提供的元信息 

要注意,一個簡單的連接也可能會收到多個connection:didReceiveResponse:消息 
當服務器連接重置或者一些罕見的原因(比如多組mime文檔),代理都會收到該消息 
這時候應該重置進度指示,丟棄之前接收的數據 

(void)connection:(NSURLConnection )connection didReceiveResponse:(NSURLResponse )response
{
//注意這裡將NSURLResponse對象轉換成NSHTTPURLResponse對象才能使用
NSHTTPURLResponse httpResponse = (NSHTTPURLResponse)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
NSDictionary *dictionary = [httpResponse allHeaderFields];
NSLog(@”%@”, dictionary);
}

[self.receiveData setLength:0];

}


當下載開始的時候,每當有數據接收,代理會定期收到connection:didReceiveData:消息 
代理應當在實現中儲存新接收的數據,下面的例子既是如此 

-(void) connection:(NSURLConnection*)connection didReceiveData:
(NSData *) data

[receiveData appendData:data];

-(void) connection:(NSURLConnection*)connection didReceiveData: 
            (NSData *) data 
{ 
   [receiveData appendData:data]; 

 } 

在上面的方法實現中,可以加入一個進度指示器,提示用戶下載進度 

當下載的過程中有錯誤發生的時候,代理會收到一個connection:didFailWithError消息 
消息參數裡面的NSError對象提供了具體的錯誤細節,它也能提供在用戶信息字典裡面失敗的 
url請求(使用NSErrorFailingURLStringKey) 

當代理接收到連接的connection:didFailWithError消息後,對於該連接不會再收到任何消息 

舉例 
(void)connection:(NSURLConnection )connection didFailWithError:(NSError )error
{

}


最後,如果連接請求成功的下載,代理會接收connectionDidFinishLoading:消息,代理不會收到其他的消息

舉例: 
(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@”總共請求的數據長度 = %d”, [self.data length]);
}

注:從ios5.0開始,蘋果為開發者引入block概念,所以使用NSURLConnection發送一個請求可以如下:

NSURL *url = [NSURL URLWithString:@”http://www.google.com“];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
NSOperationQueue *queue=[[NSOperationQueue alloc]init];

[ NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

    if (error == nil){

        NSLog(@"download success");
        NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
        NSString *str = [[NSString alloc]initWithData:data encoding:enc];
        NSLog(@"%@", str);

    }else if(error!=nil){

        NSLog(@"error");

    }

}];

“`

以上演示的請求都是GET請求,如果沒使用NSMutableURLRequest的實例方法setHTTPMethod進行設置,請求都是GET請求。
如要走POST請求,僅需:
1、將上面的NSURLRequest替換成NSMutableURLRequest
2、[request setHTTPMethod:@“POST”];
3、[request setHTTPBody:postData];//postData一般是JSON格式的字符串轉換過來的。
4、使用NSURLConnection啟動請求。


  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved