UIWebViewhtml
UIWebView是蘋果繼承於UIView封裝的一個加載web內容的類,它能夠加載任何遠端的web數據展現在你的頁面上,你能夠像瀏覽器同樣前進後退刷新等操做。不過蘋果在iOS8之後推出了WKWebView來加載Web,下面再詳細介紹下WKWebView。ios
UIWebView屬於UIKit,封裝了WebKit.framework的WebView.web
WebView組合管理了WebCore.framework的Page,並提供了各類Clients.瀏覽器
Page管理了Main Frame,Main Frame管理了sub Frame(FrameTree)(關於詳細的UIWebView介紹轉自這裏)緩存
WebView 繼承自WAKView,WAKView相似於NSView,能夠作較少的改動使得Mac和iOS共用一套。由UIWebDocumentView對 WebView進行操做並接收回調事件,當數據發生變化的時候,就會通知UIWebTiledView從新繪製。服務器
UIWebTiledView和WAKWindow這兩個類主要負責頁面的繪製,包括佈局繪圖排版,交互等,WAKWindow還會作一些用戶操做事件的分派。app
UIWebBrowserView主要負責:ide
* form的自動填充佈局
* fixed元素的位置調整post
* JavaScript的手勢識別
* 鍵盤彈出時的視圖滾動處理,防止遮擋
* 提供接口讓UIWebView獲取信息
* 爲顯示PDF時添加頁號標籤
經過反編譯能夠得到UIWebViewInternal的具體成員變量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
@interface UIWebViewInternal : NSObject
{
UIScrollView *scroller;
UIWebBrowserView *browserView;
UICheckeredPatternView *checkeredPatternView;
iddelegate;
unsigned int scalesPageToFit;
unsigned int isLoading;
unsigned int hasOverriddenOrientationChangeEventHandling;
unsigned int drawsCheckeredPattern;
unsigned int webSelectionEnabled;
unsigned int drawInWebThread;
unsigned int inRotation;
NSURLRequest *request;
int clickedAlertButtonIndex;
UIWebViewWebViewDelegate *webViewDelegate;
UIWebPDFViewHandler *pdfHandler;
}
@end
|
由此能夠看出UIWebViewInternal是接收WebView的事件的載體經過自身把WebView的事件傳遞給UIWebView.
WKWebView
經過上面的瞭解,蘋果終於在8.0以後開放了WKWebView應用於iOS和OSX中,它取代了UIWebView和WebView,在兩個平臺上支持同一套API。
它脫離於UIWebView的設計,將本來的設計拆分紅14個類,和3個代理協議,雖然是這樣可是瞭解以後其實用法比較簡單,依照職責單一的原則,每一個協議作的事情根據功能分類。
WKWebView相比於UIWebView
* WKWebView的內存遠遠沒有UIWebView的開銷大,並且沒有緩存
* 擁有高達60FPS滾動刷新率及內置手勢
* 支持了更多的HTML5特性
* 高效的app和web信息交換通道
* 容許JavaScript的Nitro庫加載並使用,UIWebView中限制了
* WKWebView目前缺乏關於頁碼相關的API
* 提供加載網頁進度的屬性
WKWebView的協議
WKScriptMessageHandler協議
1
|
window.webkit.messageHandlers.{NAME}.postMessage()
|
能夠把JavaScript對象經過該API自動轉換成Objective-C或Swift 對象,Name能夠經過addScriptMessageHandler: name:來設置
1
2
|
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
}
|
做爲惟一響應JavaScript的協議方法,目的是爲了與其它的進行分離,在該協議中響應以前注入的MessageHandlers.
能夠根據WKScriptMessage知道Js的名稱和參數,來區分不一樣的響應事件
WKNavigationDelegate協議
提 供了追蹤主窗口網頁加載過程和判斷主窗口和子窗口是否進行頁面加載新頁面的相關方法,至關於UIWebView中 webViewDidFinishLoad和webViewDidStartLoad方法,除了有開始加載、加載成功、加載失敗的API外,還具備額外的 三個代理方法:
1
2
3
|
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
|
第一個是服務器redirect時調用
第二個API是根據客戶端受到的服務器響應頭以及response相關信息來決定是否能夠跳轉
第三個API是根據WebView對於即將跳轉的HTTP請求頭信息和相關信息來決定是否跳轉
WKUIDelegate協議
提供用原生控件顯示網頁的方法回調,例如Alert提示能夠自定義用原生的控件來實現
1
2
3
4
5
6
7
|
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@
"肯定"
style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}]];
[self presentViewController:alert animated:YES completion:NULL];
}
|
總結
WKWebView 相較於UIWebView在總體上有較大的提高,知足OS上面使用同一套控件的功能,同時對整個內存的開銷以及滾動刷新率和JS交互作了優化的處理。依據 職責單一的原則,拆分紅了三個協議去實現WebView的響應,解耦了JS交互和加載進度的響應處理。WKWebView沒有作緩存處理,因此對網頁須要 緩存的加載性能要求沒那麼高的仍是能夠考慮UIWebView.
部分轉載自:http://www.cocoachina.com/ios/20160810/17337.html