昨天寫的這篇文章,今天就被推薦到首頁,上一篇博文也被微信
iOS開發(fā)公眾號轉發(fā),感謝大家的支持,以后會一直分享優(yōu)質的原創(chuàng)內容,下一篇大家想看什么,下周給大家整理更新,歡迎大家評論或者私信我,共同進步.并且昨晚有人問我UIWebView的內存優(yōu)化,今天緊急整理了一下,博文傳送門:UIWebview的內存優(yōu)化方法
微信的小應用今天內測了,所以突發(fā)奇想,給大家整理一下JS與OC交互的三種方法.
16號我的iPhone7黑色也拿到手了,文章最后放圖鎮(zhèn)樓??
其實一直想給大家整理一下JS與OC的交互,但是沒有合適的機會,今天借著微信小應用的發(fā)布,以及以后H5必定越來越流行,所以給大家整理一下.
交互方式有三種:
- 1.UIWebviewDelegate
- 2.JavaScriptCore
- 3.WebViewJavascriptBridge
按照排序給大家介紹一下,我推薦前兩種方法,第三種需要依賴第三方框架,并且不一定能攔截成功,所以著重介紹前兩種,第三種知道怎么操作就行了
1.UIWebviewDelegate
第一種也是最簡單的一種,我在實際項目中就用的這個方法,根據UIWebviewDelegate的代理方法進行攔截
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{

點擊新聞按鈕,根據shouldStartLoadWithRequest這個方法,打印出返回的url地址為
QQ20160922-0.png
QQ20160922-1.png
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSString *requestStr = [request.URL absoluteString];
NSLog(@"%@",requestStr);
//判斷返回的url是否包含news這個字符串,如果有進入if判斷,進行攔截,如果沒有,則return YES,放行;
NSRange newRange = [[requestStr lowercaseString] rangeOfString:@"news"];
if (newRange.length > 0) {
//進行你需要的操作
return NO;
}
return YES;
}
2.JavaScriptCore
這個是iOS7之后蘋果推出的一個JS于OC交互的一個框架,極大的方便了我們對js的操作
相關的幾個類
/*
JS執(zhí)行的環(huán)境,同時也通過JSVirtualMachine管理著所有對象的生命周期,每個JSValue都和JSContext相關聯并且強引用context。
*/
#import "JSContext.h"
/*
JS對象在JSVirtualMachine中的一個強引用,其實就是Hybird對象。我們對JS的操作都是通過它。并且每個JSValue都是強引用一個context。同時,OC和JS對象之間的轉換也是通過它
*/
#import "JSValue.h"
/*
JS和OC對象的內存管理輔助對象。由于JS內存管理是垃圾回收,并且JS中的對象都是強引用,而OC是引用計數。如果雙方相互引用,勢必會造成循環(huán)引用,而導致內存泄露。我們可以用JSManagedValue保存JSValue來避免。
*/
#import "JSManagedValue.h"
/*
JS運行的虛擬機,有獨立的堆空間和垃圾回收機制。
*/
#import "JSVirtualMachine.h"
/*
一個協議,如果JS對象想直接調用OC對象里面的方法和屬性,那么這個OC對象只要實現這個JSExport協議就可以了。
*/
#import "JSExport.h"
接下來就是如何去通過js來調用oc的方法了
//首先你要在本地的html文件里注冊一個按鈕,按鈕的打擊名字jsButton
<!DOCTYPE HTML>
<html lang="zh-CN">
<body>
<p>JavaScriptCore測試頁面</p>
<body>
<button onclick="jsButton()">JS按鈕</button>
</body>
</html>
//然后在加載完成的方法里通過JSContext來獲取相應操作的key值.key值是html文件里點擊方法的名字,并且調用你需要的操作
- (void)webViewDidFinishLoad:(UIWebView *)webView {
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"jsButton"] = ^{
//在這里調用你需要的操作
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"點擊了JS按鈕" message:@"" preferredStyle:(UIAlertControllerStyleAlert)];
UIAlertAction *sureAlertAction = [UIAlertAction actionWithTitle:@"OK" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
}];
[alert addAction:sureAlertAction];
[self presentViewController:alert animated:YES completion:^{
}];
};
}
3.WebViewJavascriptBridge
第三種方法是通過WebViewJavascriptBridge這個第三方庫,把js和oc之間搭建一個橋,來實現相互通信,這個是我最不推薦的一種方法,因為他需要依賴第三方庫來實現,通過互相注冊方法,增加代碼量并且并不是每次方法都能注冊上,有一定的失敗幾率,由于不推薦,所以就安排在最后,不做太詳細的解釋
3.1創(chuàng)建webview
UIWebView* webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:webView];
NSString *path = [[NSBundle mainBundle] pathForResource:@"JSBridge" ofType:@"html"];
NSURL *baseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
NSString *htmlString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[webView loadHTMLString:htmlString baseURL:baseURL];
[self.view addSubview:webView];
3.2創(chuàng)建WebViewJavascriptBridge
[WebViewJavascriptBridge enableLogging];
_bridge = [WebViewJavascriptBridge bridgeForWebView:webView];
[_bridge setWebViewDelegate:self];
3.3注冊js要調用Native
//handlerName:需要調用js的名字
//handler:需要oc進行的操作
- (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler {
[_bridge registerHandler:@"scanClick" handler:^(id data, WVJBResponseCallback responseCallback) {
//需要進行的操作
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"點擊了按鈕" message:@"" preferredStyle:(UIAlertControllerStyleAlert)];
UIAlertAction *sureAlertAction = [UIAlertAction actionWithTitle:@"OK" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
}];
[alert addAction:sureAlertAction];
[self presentViewController:alert animated:YES completion:^{
}];
}];
和我之前的6s比起來就是,比好更好,套用蘋果式的廣告語

