UIWebView的js和OC交互方式
其包括三種方式:
第一種::UIWebViewDelegate(代理方法)
第二種: JavaScriptCore
第三種: WebViewJavascript Bridge
下面就按照順序依次展開,我推薦使用前兩種,因為第三種需要依賴第三方框架,還有個缺點就是不一定能夠攔截成功,第三種方法知道就行了.廢話不多說開始正題.
一.UIWebViewDelegate
這種方式是最簡單的,我在實際項目中用的就是這一種,簡單方便實用,主要是根據(jù)UIWebViewDelegate的代理方法進行攔截.
-(BOOL)webView:(UIWebView *)webViewshouldStartLoadWithRequest:(NSURLRequest *)requestnavigationType:(UIWebViewNavigationType)navigationType{}
例如:www.baidu.com網(wǎng)頁為例
點擊新聞按鈕,根據(jù)shouldStartLoadWithRequest這個方法,打印出返回的url地址為
-(BOOL)webView:(UIWebView *)webViewshouldStartLoadWithRequest:(NSURLRequest *)requestnavigationType:(UIWebViewNavigationType)navigationType{
? ? ? NSString *requestStr = [request.URL absoluteString];
NSLog(@"%@",requestStr);
}
-(BOOL)webView:(UIWebView *)webViewshouldStartLoadWithRequest:(NSURLRequest *)requestnavigationType:(UIWebViewNavigationType)navigationType{
NSString *requestStr=[request.URLabsoluteString];
NSLog(@"%@",requestStr);
//判斷返回的url是否包含news這個字符串,如果有進入if判斷,進行攔截,如果沒有,則return YES,放行;
NSRangenewRange=[[requestStrlowercaseString]rangeOfString:@"news"];
if(newRange.length>0){
//進行你需要的操作
returnNO;
}
returnYES;
}
二.JavaScriptCore(這個是iOS7之后蘋果推出的一JS和OC交互的一個框架,極大的方便了我們對js的操作)
相關(guān)的幾個類
/*
JS執(zhí)行的環(huán)境评甜,同時也通過JSVirtualMachine管理著所有對象的生命周期灰粮,每個JSValue都和JSContext相關(guān)聯(lián)并且強引用context。
*/
#import "JSContext.h"
/*
JS對象在JSVirtualMachine中的一個強引用忍坷,其實就是Hybird對象粘舟。我們對JS的操作都是通過它。并且每個JSValue都是強引用一個context佩研。同時柑肴,OC和JS對象之間的轉(zhuǎn)換也是通過它
*/
#import "JSValue.h"
/*
JS和OC對象的內(nèi)存管理輔助對象。由于JS內(nèi)存管理是垃圾回收旬薯,并且JS中的對象都是強引用晰骑,而OC是引用計數(shù)。如果雙方相互引用绊序,勢必會造成循環(huán)引用硕舆,而導(dǎo)致內(nèi)存泄露。我們可以用JSManagedValue保存JSValue來避免骤公。
*/
#import "JSManagedValue.h"
/*
JS運行的虛擬機抚官,有獨立的堆空間和垃圾回收機制。
*/
#import "JSVirtualMachine.h"
/*
一個協(xié)議阶捆,如果JS對象想直接調(diào)用OC對象里面的方法和屬性凌节,那么這個OC對象只要實現(xiàn)這個JSExport協(xié)議就可以了。
*/
#import "JSExport.h"
接下來就是如何去通過js來調(diào)用oc的方法了
//首先你要在本地的html文件里注冊一個按鈕,按鈕的打擊名字jsButton
JavaScriptCore測試頁面
//首先你要在本地的html文件里注冊一個按鈕,按鈕的打擊名字jsButton
JavaScriptCore測試頁面
JS按鈕
//然后在加載完成的方法里通過JSContext來獲取相應(yīng)操作的key值.key值是html文件里點擊方法的名字,并且調(diào)用你需要的操作
-(void)webViewDidFinishLoad:(UIWebView *)webView{
JSContext *context=[self.webViewvalueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"jsButton"]= ^{
//在這里調(diào)用你需要的操作
UIAlertController *alert=[UIAlertControlleralertControllerWithTitle:@"點擊了JS按鈕"message:@""preferredStyle:(UIAlertControllerStyleAlert)];
UIAlertAction *sureAlertAction=[UIAlertActionactionWithTitle:@"OK"style:(UIAlertActionStyleDefault)handler:^(UIAlertAction *_Nonnullaction){
}];
[alertaddAction:sureAlertAction];
[selfpresentViewController:alertanimated:YEScompletion:^{
}];
};
}
三.WebViewJavascriptBridge
第三種方法是通過WebViewJavascriptBridge這個第三方庫,把js和oc之間搭建一個橋,來實現(xiàn)相互通信,這個是我最不推薦的一種方法,因為他需要依賴第三方庫來實現(xiàn),通過互相注冊方法,增加代碼量并且并不是每次方法都能注冊上,有一定的失敗幾率,由于不推薦,所以就安排在最后,不做太詳細的解釋
3.1創(chuàng)建webview
UIWebView*webView=[[UIWebViewalloc]initWithFrame:self.view.bounds];
[self.viewaddSubview:webView];
NSString *path=[[NSBundlemainBundle]pathForResource:@"JSBridge"ofType:@"html"];
NSURL *baseURL=[NSURLfileURLWithPath:[[NSBundlemainBundle]bundlePath]];
NSString *htmlString=[NSStringstringWithContentsOfFile:pathencoding:NSUTF8StringEncodingerror:nil];
[webViewloadHTMLString:htmlStringbaseURL:baseURL];
[self.viewaddSubview:webView];
3.2創(chuàng)建WebViewJavascriptBridge
[WebViewJavascriptBridgeenableLogging];
_bridge=[WebViewJavascriptBridgebridgeForWebView:webView];
[_bridgesetWebViewDelegate:self];
3.3注冊js要調(diào)用Native
//handlerName:需要調(diào)用js的名字
//handler:需要oc進行的操作
-(void)registerHandler:(NSString *)handlerNamehandler:(WVJBHandler)handler{
[_bridgeregisterHandler:@"scanClick"handler:^(iddata,WVJBResponseCallbackresponseCallback){
//需要進行的操作
UIAlertController *alert=[UIAlertControlleralertControllerWithTitle:@"點擊了按鈕"message:@""preferredStyle:(UIAlertControllerStyleAlert)];
UIAlertAction *sureAlertAction=[UIAlertActionactionWithTitle:@"OK"style:(UIAlertActionStyleDefault)handler:^(UIAlertAction *_Nonnullaction){
}];
[alertaddAction:sureAlertAction];
[selfpresentViewController:alertanimated:YEScompletion:^{
}];
}];