0

How can I get a URL from webView whenever the URL is changed?

I want to change the button color when current URL is changed. So I need to check the current URL all the time.

And I also would like to get URL value as a String.

I tried the below code but it doesn't work at all.

NotificationCenter.default.addObserver(self, selector: #selector(urlChecker), name: NSNotification.Name.NSURLCredentialStorageChanged, object: webView)
김동현
  • 91
  • 3
  • 14

1 Answers1

2

you can use:

1. Solution

UIWebViewDelegate

https://developer.apple.com/reference/uikit/uiwebviewdelegate/1617945-webview

optional func webView(_ webView: UIWebView, 
  shouldStartLoadWith request: URLRequest, 
       navigationType: UIWebViewNavigationType) -> Bool

UIWebViewNavigationType:

https://developer.apple.com/reference/uikit/uiwebviewnavigationtype

don't forget to return true

case linkClicked

User tapped a link.

case formSubmitted

User submitted a form.

case backForward

User tapped the back or forward button.

case reload

User tapped the reload button.

case formResubmitted

User resubmitted a form.

case other

Some other action occurred.

2. Solution

Inject Javascript JavaScript MessageHandler

(credit to Vasily Bodnarchuk)

Solution is here: https://stackoverflow.com/a/40730365/1930509

Swift 3 example.

Description

The script is inserted into page which will displayed in WKWebView. This script will return the page URL (but you can write another JavaScript code). This means that the script event is generated on the web page, but it will be handled in our function:

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {...}

Full Code example

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {

    var webView = WKWebView()
    let getUrlAtDocumentStartScript = "GetUrlAtDocumentStart"
    let getUrlAtDocumentEndScript = "GetUrlAtDocumentEnd"
     override func viewDidLoad() {
             super.viewDidLoad()

            let config = WKWebViewConfiguration()
            config.addScript(script: WKUserScript.getUrlScript(scriptName: getUrlAtDocumentStartScript),
 scriptHandlerName:getUrlAtDocumentStartScript, scriptMessageHandler:
 self, injectionTime: .atDocumentStart)
            config.addScript(script: WKUserScript.getUrlScript(scriptName: getUrlAtDocumentEndScript),
scriptHandlerName:getUrlAtDocumentEndScript, scriptMessageHandler:
self, injectionTime: .atDocumentEnd)


             webView = WKWebView(frame:  UIScreen.main.bounds, configuration: config)
            webView.navigationDelegate = self
             view.addSubview(webView)
        }

     override func viewDidAppear(_ animated: Bool) {
         super.viewDidAppear(animated)
         webView.loadUrl(string: "http://apple.com")
    }
}
extension ViewController: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        switch message.name {

            case getUrlAtDocumentStartScript:
                print("start: \(message.body)")

            case getUrlAtDocumentEndScript:
                print("end: \(message.body)")

            default:
                break;
        }
    }
}

extension WKUserScript {
    class func getUrlScript(scriptName: String) -> String {
        return "webkit.messageHandlers.\(scriptName).postMessage(document.URL)"
    }
}

extension WKWebView {
    func loadUrl(string: String) {
        if let url = URL(string: string) {
            load(URLRequest(url: url))
        }
    }
}
 extension WKWebViewConfiguration {
        func addScript(script: String, scriptHandlerName:String, scriptMessageHandler: WKScriptMessageHandler,injectionTime:WKUserScriptInjectionTime) {
             let userScript = WKUserScript(source: script, injectionTime: injectionTime, forMainFrameOnly: false)
             userContentController.addUserScript(userScript)
             userContentController.add(scriptMessageHandler, name: scriptHandlerName)
        }
    }

Info.plist

add in your Info.plist transport security setting

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

Result

enter image description here

Resources ##

Document Object Properties and Methods

Himanshu Moradiya
  • 4,769
  • 4
  • 25
  • 49
muescha
  • 1,544
  • 2
  • 12
  • 22