VDWebView提供了最全的API調用和最方便的JS交互方式,可經過pod更新迭代;設計方案爲Protocol和Target-Action;有任何意見或者問題歡迎指出。html
pod 'VDWebView', '~> 1.0.3'
複製代碼
WKWebView
是iOS8後推出的WebKit框架中的控件,因爲iOS12後已經棄用UIWebView
了並且如今的大多數項目只適配到iOS8UIWebView
且解決了加載網頁時的內存泄露問題WKUserContentController
UIWebView
代理方法,處理對象(WKNavigationDelegate
)/// 類UIWebView代理方法
- (void)webViewDidStartLoad:(VDWebView *)webView;
- (void)webViewDidFinishLoad:(VDWebView *)webView;
- (void)webView:(VDWebView *)webView didFailLoadWithError:(NSError *)error;
- (BOOL)webView:(VDWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
複製代碼
WKUIDelegate
和WKScriptMessageHandler
代理的合併/**
JS調原生代理方法(註冊了過的方法將所有經過此方法回調)
*/
- (void)webView:(VDWebView *)webView didReceiveScriptMessage:(WKScriptMessage *)message;
/**
JS彈框攔截方法--若是須要自定義彈框建議聲明此方法
*/
- (void)webView:(VDWebView *)webView showAlertWithType:(VDJSAlertType)type title:(NSString *)title content:(NSString *)content completionHandler:(void (^)(id))completionHandler;
複製代碼
詳情可見VDWebViewProtocol
java
///預估網頁加載進度
@property (nonatomic, readonly) CGFloat estimatedProgress;
// 是否顯示進度條 默認不顯示
@property (nonatomic, assign) BOOL isShowProgressBar;
///進度條
@property (nonatomic, strong) UIView *progressBar;
/**
web頁面加載完畢後的內容高度(在頁面加載完成後獲取)
*/
@property (nonatomic, readonly) CGFloat *contentHeight;
/// 是否啓用js調用原生彈框 默認爲NO 禁止(默認加載彈框在根試圖)
@property (nonatomic, assign) BOOL enableAllAlert;
@property (nonatomic, assign) BOOL enableAlert;
@property (nonatomic, assign) BOOL enableConfirm;
@property (nonatomic, assign) BOOL enablePrompt;
///back 層數
- (NSInteger)countOfHistory;
- (void)gobackWithStep:(NSInteger)step;
複製代碼
在使用WKWebView
時咱們須要調用WKWebView
內configuration
中的userContentController
所屬類WKUserContentController
提供的實例方法進行註冊,具體方法以下:git
- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;
複製代碼
對應的註銷方法爲:github
- (void)removeScriptMessageHandlerForName:(NSString *)name;
複製代碼
在使用addScriptMessageHandler:name:
方法註冊時傳入的這個handler被循環引用,若是不調用對應的註銷方法就會致使handler這個對象沒法被釋放,若是你這個handler傳入是webView所在的控制器,那麼你就要在銷燬這個控制器前註銷掉你註冊的方法.web
tip: 如何知道控制器有沒有被釋放,重寫dealloc(),沒走此方法說明未被釋放json
簡要分析可分爲下面三步安全
VDScripMessageHandler
做爲註冊的handler
WKScriptMessageHandler
VDWebView
的dealloc()
方法中獲取註冊記錄並註銷這些作的好處在於你在使用VDWebView時無需本身去一個個手動註銷了(若是你註冊的方法多的話那就是噩夢了)bash
- (void)addScriptMessageHandler:(id)scriptMessageHandler name:(NSString *)name;
複製代碼
// 沒效果可以使用try-catch
window.webkit.messageHandlers.#OC方法名#.postMessage(#參數#)
複製代碼
回調方式分兩種:delegate和target-action; 兩種方式只能存一,優先delegatecookie
VDWebViewDelegate
中的方法- (void)webView:(VDWebView *)webView didReceiveScriptMessage:(WKScriptMessage *)message;
複製代碼
target-action:目標-動做模式,拜C語言所賜,更是靈活不少,編譯期沒有任何檢查,都是運行時的綁定框架
VDWebView
中就是經過NSSelectorFromString()
動態加載方法,再經過NSMethodSignature
和NSInvocation
進行方法的簽名和調用可經過兩種方式進行JS方法的調用,推薦第一種
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^)(id, NSError *))completionHandler;
複製代碼
- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)javaScriptString;
複製代碼
腳本的注入和移除
/**
注入腳本(js...)
*/
- (void)addUserScriptWithSource:(NSString *)source injectionTime:(WKUserScriptInjectionTime)injectionTime forMainFrameOnly:(BOOL)mainFrameOnly;
/**
移除全部注入的腳本
*/
- (void)removeAllUserScripts;
複製代碼
VDWebViewCookiesProtocol
因爲WKWebView的cookie是和NSHTTPCookieStorage不共享,這就形成使用WKWebView打開的web頁面沒法獲取到經過原生請求登陸的cookie,固然其它解決方案有不少種,好比
可是用了VDWebView就不須要考慮cookie的問題了,由於它已經默認把cookie帶過去了,固然你也能夠手動去關閉
/**
不一樣步NSHTTPCookieStorage存儲的cookies 默認同步:NO
同步NSHTTPCookieStorage中的cookie到WKWebView中,有可能會污染WKWebView中的cookie管理
*/
@property (nonatomic, assign)BOOL httpCookiesDisable;
複製代碼
/**
設置cookie
*/
- (void)setCookieWithKey:(NSString *)key value:(NSString *)value expires:(NSTimeInterval)expires domain:(NSString *)domain;
- (void)setCookies:(NSString *)cookies;
/**
獲取cookie
*/
- (NSArray *)getCookies;
複製代碼
VDWebViewJSBridge
你只須要調用VDWebView
繼承的協議VDWebViewProtocol
所提供的初始化方法bridgeInitialized
便可
// 調用初始化 在webView的控制器中實現同名方法
self.webView.delegate = self;
[self.webView bridgeInitialized];
複製代碼
與對應的js配套使用,此方案適用於iOS和Android對應的js文件以下
// 在js中直接調用VDJSWebBridge.js提供的方法,詳情請查看js
// methodName爲控制器中聲明的方法名,params爲json字符串
vd_jsBridge(methodName, params)
複製代碼
// JS 方法
function jsMethod(param1, param2, param3) {
alert("使用jsBridge調用js方法成功參數爲:"+param1+param2+param3)
return "success";
}
// OC調用JS方法
[self.webView.bridge executeJsMethod:@"jsMethod" params:@[@"1",@"2",@"3"] completionHandler:^(id result, NSError *error) {
NSLog(@"\njs方法執行h結果回調:%@\n錯誤信息:%@",result,error);
}];
複製代碼