WKWebView 是 iOS 開發中用於顯示網頁內容的組件,它是在 iOS 8 中引入的,作為 UIWebView 的替代品。WKWebView 提供了更高的性能和更多的功能,它是基於 WebKit 引擎的,這也是 Safari 瀏覽器所使用的引擎。 主要特性 性能提升:相比於老舊的 UIWebV ...
WKWebView
是 iOS 開發中用於顯示網頁內容的組件,它是在 iOS 8 中引入的,作為 UIWebView
的替代品。WKWebView
提供了更高的性能和更多的功能,它是基於 WebKit 引擎的,這也是 Safari 瀏覽器所使用的引擎。
主要特性
- 性能提升:相比於老舊的
UIWebView
,WKWebView
在性能上有顯著提升,包括更快的JavaScript執行和更流暢的頁面渲染。 - 獨立的進程:
WKWebView
在獨立的進程中運行,這意味著即使網頁內容崩潰,也不會影響到應用程式的其他部分。 - 現代化的API:提供了一套現代化的API,允許開發者與網頁內容進行更深層次的交互。
- 安全性:預設禁用了跨站點跟蹤,並支持內容安全策略(CSP)。
使用 WKWebView
要在應用中使用 WKWebView
,首先需要導入 WebKit
框架:
#import <WebKit/WebKit.h>
然後,可以創建一個 WKWebView
實例並添加到視圖中:
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
[self.view addSubview:webView];
載入網頁非常簡單,可以使用一個 NSURLRequest
來載入一個網頁:
NSURL *url = [NSURL URLWithString:@"https://www.example.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
與網頁內容交互
WKWebView
提供了 WKScriptMessageHandler
協議,允許原生代碼與網頁中的JavaScript相互通信。可以註入JavaScript代碼並捕獲其執行結果,或者讓網頁調用原生代碼。
// 添加一個名為 "appModel" 的腳本消息處理器
[webView.configuration.userContentController addScriptMessageHandler:self name:@"appModel"];
// 實現 WKScriptMessageHandler 協議的方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if ([message.name isEqualToString:@"appModel"]) {
// 處理從網頁接收到的消息
NSLog(@"JavaScript is sending a message: %@", message.body);
}
}
導航代理和 UI 代理
WKWebView
提供了兩個代理協議:WKNavigationDelegate
和 WKUIDelegate
。這些代理協議允許追蹤網頁載入的進度、處理網頁載入過程中的各種事件、以及自定義網頁中的某些UI元素,如彈出框。
webView.navigationDelegate = self;
webView.UIDelegate = self;
// 實現 WKNavigationDelegate 協議的方法來追蹤載入進度
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
NSLog(@"網頁載入完成");
}
// 實現 WKUIDelegate 協議的方法來自定義UI元素
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
// 顯示一個自定義的彈出框
completionHandler();
}