Как получить значение URL KVO #keyPath (WKWebView.url)? - PullRequest
0 голосов
/ 11 февраля 2020

Я опубликовал более подробный вопрос , чтобы попытаться разобраться в сути проблемы, но вкратце:

Я пытаюсь показать PHP / JS веб-приложение (Laravel) через WKWebView. Однако из-за характера свойств перенаправления скрипта единственный код, который я получил для фактического обнаружения изменения URL, - это #keyPath(WKWebView.url):

override func viewDidLoad() {
    super.viewDidLoad()

    webView.navigationDelegate = self
    webView.uiDelegate = self    
    webView.addObserver(self, forKeyPath: #keyPath(WKWebView.url), options: .new, context: nil)
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath == #keyPath(WKWebView.url) {
        print("URL Change:", self.webView.url?.absoluteString ?? "# No value provided")
    }
}

Однако вывод на консоль всегда одинаков :

URL Change: # No value provided

Итак, я знаю, что KVO для WKWebView.url может запускать перенаправление на основе сценариев в WebView. На самом деле, если вы посмотрите на мой другой вопрос , это единственный код, который может обнаружить такое перенаправление - что странно, потому что при запуске в Safari (как iOS, так и macOS), Панель URL может отражать эти перенаправленные изменения в значении URL. Однако в WKWebView ни одна из функций WKNavigationDelegate не может обнаружить такое изменение URL-адреса.

Есть ли способ получить URL-адрес непосредственно из значения keyPath WKWebView.url при срабатывании? Существуют ли какие-либо альтернативы, не описанные в моем ранее упомянутом вопросе, которые могли бы получить URL?

При попытке получить значение URL из webView.url, кажется, всегда возвращается ноль.

РЕДАКТИРОВАТЬ: Я могу получить точное значение URL с помощью кода функции ObserverValue:

if let key = change?[NSKeyValueChangeKey.newKey] {
    print("URL: \(key)") // url value
}

Однако я не могу преобразовать его как строку или передать его другой функции в противном случае. Есть ли способ установить этот ключ как переменную, если он .contains ("https: //")?

1 Ответ

0 голосов
/ 12 февраля 2020

Мне удалось присвоить KVO WKWebView.url строковой переменной. Оттуда я смог передать значение String в функцию, которая затем обрабатывает каждый вывод, который я ищу:

var cURL = ""

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if let key = change?[NSKeyValueChangeKey.newKey] {
        cURL = "\(key)"         // Assign key-value to String
        print("cURL:", cURL)    // Print key-value
        cURLChange(url: cURL)   // Pass key-value to function
    }
}

func cURLChange(url: String) {
    if cURL.contains("/projects/new") {
        print("User launched new project view")
        // Do something
    } else {
        // Do something else
    }
}

Аналогичное решение с использованием более современного метода (с меньшими трудностями ), было предоставлено здесь .

var cURL = ""
var webView: WKWebView!
var webViewURLObserver: NSKeyValueObservation?

override func viewDidLoad() {
    super.viewDidLoad()

    // 1. Assign changed value to variable
    webViewURLObserver = webView.observe(\.url, options: .new) { webView, change in
        self.cURL = "\(String(describing: change.newValue))" }

    // 2. Print value of WKWebView URL
    webViewURLObserver = webView.observe(\.url, options: .new) { webView, change in
        print("URL: \(String(describing: change.newValue))"
    )}

Используя NSKeyValueObservation для объекта, вам не нужно удалять наблюдателей или проверять значения наблюдателей с помощью keyPath. Вы можете просто настроить его на наблюдение объекта (ie. WKWebView) и запускать код при обнаружении изменения.

...