需求
iOS 項目中 wkwebview 實現的 web 容器,需要監聽 web 容器內的所有網絡請求
實現
在 iOS 項目中使用 WKWebView
實現的 Web 容器,監聽 Web 容器內的網絡請求是一個常見需求。可以通過實現 WKURLSchemeHandler
協議來處理自定義的 URL scheme,從而攔截和監聽網絡請求。以下是一個優秀的實現方案:
實現步驟
- 創建自定義 URL Scheme Handler
首先,創建一個新的類實現 WKURLSchemeHandler
協議,例如 CustomURLSchemeHandler
:
import WebKitclass CustomURLSchemeHandler: NSObject, WKURLSchemeHandler {func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {let url = urlSchemeTask.request.url!// 打印或處理請求print("Request URL: \(url.absoluteString)")// 這里可以進行自定義處理,如加載本地資源或轉發請求// 示例:直接返回一個空白頁面let response = HTTPURLResponse(url: url, statusCode: 200, httpVersion: nil, headerFields: nil)!let data = Data()urlSchemeTask.didReceive(response)urlSchemeTask.didReceive(data)urlSchemeTask.didFinish()}func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {// 處理請求取消邏輯}
}
- 配置
WKWebViewConfiguration
并注冊自定義 Scheme Handler
創建并配置 WKWebViewConfiguration
,然后注冊自定義的 URL Scheme Handler:
let config = WKWebViewConfiguration()
let schemeHandler = CustomURLSchemeHandler()
config.setURLSchemeHandler(schemeHandler, forURLScheme: "https")let webView = WKWebView(frame: .zero, configuration: config)
- 加載 Web 內容
最后,使用 WKWebView
加載需要的 Web 內容:
let request = URLRequest(url: URL(string: "https://example.com")!)
webView.load(request)
完整示例代碼
以下是完整的實現代碼:
import UIKit
import WebKitclass ViewController: UIViewController {var webView: WKWebView!override func viewDidLoad() {super.viewDidLoad()let config = WKWebViewConfiguration()let schemeHandler = CustomURLSchemeHandler()config.setURLSchemeHandler(schemeHandler, forURLScheme: "https")webView = WKWebView(frame: self.view.bounds, configuration: config)self.view.addSubview(webView)let request = URLRequest(url: URL(string: "https://example.com")!)webView.load(request)}
}class CustomURLSchemeHandler: NSObject, WKURLSchemeHandler {func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {let url = urlSchemeTask.request.url!print("Request URL: \(url.absoluteString)")// 這里可以進行自定義處理,如加載本地資源或轉發請求// 示例:直接返回一個空白頁面let response = HTTPURLResponse(url: url, statusCode: 200, httpVersion: nil, headerFields: nil)!let data = Data()urlSchemeTask.didReceive(response)urlSchemeTask.didReceive(data)urlSchemeTask.didFinish()}func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {// 處理請求取消邏輯}
}
總結
通過實現 WKURLSchemeHandler
并注冊自定義的 URL scheme,可以輕松監聽并處理 WKWebView
內的所有網絡請求。這種方法不僅可以用于調試和日志記錄,還可以實現高級的請求攔截和處理邏輯。
更新:這是一個錯誤的方案
上面的代碼有一個問題:WKWebView
的 setURLSchemeHandler(_:forURLScheme:)
方法不允許處理 https
和 http
URL scheme。這是因為這些 URL schemes 是由系統處理的,不能被自定義的 scheme handler 覆蓋。
這里是修正的代碼示例,使用一個自定義的 URL scheme,例如 customscheme
:
import WebKitclass CustomURLSchemeHandler: NSObject, WKURLSchemeHandler {func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {// 自定義處理 URL 請求的邏輯}func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {// 自定義停止處理 URL 請求的邏輯}
}let config = WKWebViewConfiguration()
let schemeHandler = CustomURLSchemeHandler()
config.setURLSchemeHandler(schemeHandler, forURLScheme: "customscheme")let webView = WKWebView(frame: .zero, configuration: config)// 測試加載自定義 scheme 的 URL
if let url = URL(string: "customscheme://example") {let request = URLRequest(url: url)webView.load(request)
}
在這個示例中,我們使用了一個自定義的 URL scheme (customscheme
),并創建了一個自定義的 WKURLSchemeHandler
來處理這個 scheme 的 URL 請求。這樣就避免了覆蓋系統處理的 https
和 http
URL schemes 的問題。