1

We need to add query parameter (isfromMobile=true ) in every webpage URL, which is required to identify that the request is from the mobile app at the backend. it's absolutely fine loading on the first page, however, if I click on the link inside webview the url changes which is completely a new URL for backend system, As per the logic, mobile app should embed query parameter on this URL as well. I tried fixing the same with following delegate method of webview.

func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    request.url = request.url?.getMobileUrl() // this adds the query parameter in url eg : testurl?isFromMobile=true
    return true
}

However, I observed the request parameter is not mutable in this delegate, creating everytime a new request will definitely increase the web URL loading time or I would not prefer that. Any better suggestion for the same.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Dipesh Pokhrel
  • 386
  • 5
  • 20

2 Answers2

2

First, do use WKWebView. Then you can tap into WKNavigationDelegate decidePolicyForNavigationAction method to check for the loading url and if it doesn't have your required query parameters adjust the url and reload it:

class ViewController: UIViewController, WKNavigationDelegate  {
    var webView: WKWebView?
    var loadUrl = URL(string: "https://stackoverflow.com/tags?isFromMobile=true")!

    override func viewDidLoad() {
        super.viewDidLoad()
        // .. all your other code here

        // Load first request with initial url
        loadWebPage(url: loadUrl)
    }

    func loadWebPage(url: URL)  {
        var components = URLComponents(url: url, resolvingAgainstBaseURL: false)
    components?.query = nil

        // If already has a query then append a param
        // otherwise create a new one
        if let query = url.query {
            // If isFromMobile param already exists jsut reassign the existing query
            if query.contains("isFromMobile=true") {
                components?.query = query
            } else {
                 components?.query = query + "&isFromMobile=true"
            }
        } else {
            components?.query = "isFromMobile=true"
        }

        let customRequest = URLRequest(url: components!.url!)
        loadUrl = components!.url!
        webView!.load(customRequest)
    }

    // MARK: - WKNavigationDelegate

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        guard let url = navigationAction.request.url else {
            decisionHandler(.cancel)
            return
        }

        // If url changes, cancel current request which has no custom parameters
        // and load a new request with that url with custom parameters
        if url != loadUrl {
            decisionHandler(.cancel)
            loadWebPage(url: url)
         } else {
            decisionHandler(.allow)
         }
     }
 }
Au Ris
  • 4,541
  • 2
  • 26
  • 53
  • Thanks for your answer But, I need to provide support for the lower versions as well and need to maintain the webview stack(user should be able to come back previous ) as well. – Dipesh Pokhrel Jul 13 '18 at 11:00
  • Seriously, you need to support lower than iOS 8? – Au Ris Jul 13 '18 at 11:05
  • I wish I could provide support above iOS 8 version only. – Dipesh Pokhrel Jul 13 '18 at 11:08
  • very nice approach but this will start appending isFromMobile=true with all the urls in your webpage and then load them which you might do not want, if you only want to append this parameter with your main url , this thread can help [link]https://stackoverflow.com/questions/44408420/getting-the-link-url-tapped-in-wkwebview – Muhammad Ali Mar 02 '20 at 11:43
  • It is not very difficult to check to which URL you want to append the parameters :) – Au Ris Mar 02 '20 at 12:05
0

First of all, while searching around in the apple documentation, I have found multiple things.

First of all, you are using the UIWebview which is deprecated. You should use WKWebView. From the docs:

Important Starting in iOS 8.0 and OS X 10.10, use WKWebView to add web content to your app. Do not use UIWebView or WebView.

When searching the documentation for the WKWebView, there is a method you could use, called load(_:).

So you would override this method, change the url to contain the (isFromMobile=true) and then call the super method with the updated url.

Hope this could help.

J.Paravicini
  • 882
  • 12
  • 39