最近的一個項目中需要實現(xiàn)OC與JS的交互,在iOS中實現(xiàn)方法有三種,本文主要介紹下UIWebView如何與JS交互。
一、UIWebView的基本用法
1、加載網(wǎng)頁
//加載本地文件
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
NSString * htmlPath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSString * htmlCont = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil];
[self.webView loadHTMLString:htmlCont baseURL:baseURL];
//直接加載網(wǎng)頁
NSURL *url = [[NSURL alloc] initWithString:@"http://www.baidu.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
注意:將網(wǎng)頁作為本地文件加載的好處是能更好的與本地文件進行交互,如果你想把手機圖片傳給js,只需要把圖片保存的路徑傳入即可。直接加載網(wǎng)頁的情況下需要將圖片進行base64編碼。具體參考這篇文章http://www.cnblogs.com/HwangKop/p/5010275.html。
2、代理方法
//每當webView加載一個請求都會來到這個方法,返回YES允許加載,然后StartLoad、FinishLoad,返回NO則不加載這個請求
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
//開始加載網(wǎng)頁的回調(diào)
- (void)webViewDidStartLoad:(UIWebView *)webView;
//網(wǎng)頁加載完畢的回調(diào)
- (void)webViewDidFinishLoad:(UIWebView *)webView;
//網(wǎng)頁加載失敗的回調(diào)
- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error;
二、UIWebView與JS交互
1、OC調(diào)用JS
OC調(diào)用JS主要通過使用- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;這個方法來實現(xiàn)。傳入你要執(zhí)行的JS代碼塊,如果有返回值,可以接收NSString類型作為返回值。下面是獲取網(wǎng)頁Title并給導航控制器Title賦值的代碼。
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
//獲取網(wǎng)頁的title
self.navigationItem.title = [self.webView stringByEvaluatingJavaScriptFromString:@"document.title"];
}
注意:調(diào)用web頁面中的需要傳參的函數(shù)時,參數(shù)需要帶單引號,或者雙引號(雙引號需要進行轉義在轉義字符前加\),并且OC與JS交互只能傳字符串類型,所以在調(diào)用前需轉換成NSString類型。
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSString *loginStr = [NSString stringWithFormat:@"loggedIn('%@','%@','%@')",[USER_DEFAULT objectForKey:KUID],[USER_DEFAULT objectForKey:KPhoneNumber],[USER_DEFAULT objectForKey:KNICKNAME]];
ZYLog(@"%@",loginStr);
[self.webView stringByEvaluatingJavaScriptFromString:loginStr];
}
2、JS調(diào)用OC
JS調(diào)用OC主要通過使用 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;這個方法。這種方式是用JS發(fā)起一個假的URL請求,然后利用UIWebView的代理方法攔截這次請求,然后再做相應的處理。
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
// 獲取請求路徑
NSString *url = request.URL.absoluteString;
// 定義的協(xié)議
NSString *scheme = @"ios://";
if ([url hasPrefix:scheme]) {
// 獲得協(xié)議后面的路徑 path == sendMessage:message2:?200&300
NSString *path = [url substringFromIndex:scheme.length];
// 利用?切割路徑 分割方法與參數(shù)
NSArray *subpaths = [path componentsSeparatedByString:@"?"];
// 方法名 methodName == sendMessage:number2:
NSString *methodName = [subpaths firstObject];
// 參數(shù) 200&300
NSArray *params = nil;
if (subpaths.count == 2) {
params = [[subpaths lastObject] componentsSeparatedByString:@"&"];
}
// 調(diào)用本地函數(shù)
[self performSelector:NSSelectorFromString(methodName) withObjects:params];
return NO;
}
NSLog(@"想加載其他請求,不是想調(diào)用OC的方法");
return YES;
}
注意:系統(tǒng)提供的performSelector函數(shù)至多只能傳兩個參數(shù),如果想實現(xiàn)多個參數(shù)傳遞,參考這篇文章http://www.itdecent.cn/p/c2415b064e20