Я наконец нашел решение этой проблемы. Существует множество решений, но все они используют jQuery, который, похоже, не работает в WKWebView
. Вот мое решение в raw JavaScript
.
Вот реализация ViewController, которая позволяет получать уведомления о каждом запросе AJAX, выполненном в WKWebView
:
import UIKit
import WebKit
class WebViewController: UIViewController {
private var wkWebView: WKWebView!
private let handler = "handler"
override func viewDidLoad() {
super.viewDidLoad()
let config = WKWebViewConfiguration()
let userScript = WKUserScript(source: getScript(), injectionTime: .atDocumentStart, forMainFrameOnly: false)
config.userContentController.addUserScript(userScript)
config.userContentController.add(self, name: handler)
wkWebView = WKWebView(frame: view.bounds, configuration: config)
view.addSubview(wkWebView)
if let url = URL(string: "YOUR AJAX WEBSITE") {
wkWebView.load(URLRequest(url: url))
} else {
print("Wrong URL!")
}
}
private func getScript() -> String {
if let filepath = Bundle.main.path(forResource: "script", ofType: "js") {
do {
return try String(contentsOfFile: filepath)
} catch {
print(error)
}
} else {
print("script.js not found!")
}
return ""
}
}
extension WebViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if let dict = message.body as? Dictionary<String, AnyObject>, let status = dict["status"] as? Int, let responseUrl = dict["responseURL"] as? String {
print(status)
print(responseUrl)
}
}
}
Довольно стандартная реализация. WKWebView
создан программно. Существует внедренный скрипт, который загружается из файла script.js
.
И наиболее важной частью является script.js
файл:
var open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function() {
this.addEventListener("load", function() {
var message = {"status" : this.status, "responseURL" : this.responseURL}
webkit.messageHandlers.handler.postMessage(message);
});
open.apply(this, arguments);
};
userContentController
метод делегата будет вызываться каждый раз, когда загружается AJAX-запрос. Я передаю туда status
и responseURL
, потому что это было то, что мне было нужно в моем случае, но вы также можете получить больше информации о запросе. Вот список всех доступных свойств и методов:
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
Мое решение вдохновлено этим ответом, написанным @John Culviner:
https://stackoverflow.com/a/27363569/3448282