【问题标题】:UIWebView get current URL of SPA (single page application) websiteUIWebView 获取 SPA(单页应用)网站的当前 URL
【发布时间】:2019-05-20 17:57:51
【问题描述】:

我想在浏览 SPA (single-page-application) 网站时获取我的 UIWebView 的当前位置。
(是的,我有意使用 UIWebView 而不是 WKWebView。)

我知道有multiple approaches来获取当前的URL,比如:

webView.request?.url?.absoluteString
webView.request?.mainDocumentURL?.absoluteString
webView.stringByEvaluatingJavaScript(from: "window.location")

但是,对于 SPA 网站,对于上述每种方法,我都会获得初始 URL,即使我导航到该 SPA 网站上的另一个页面也是如此。

我能做什么?

【问题讨论】:

  • 您可以有一个自定义的 URLProtocol,它拦截 UIWebView 中发出的所有 URL 请求以确定您的当前位置(假设您对“当前位置”的定义可以由 URL 请求确定)。
  • 您的意思是使用诸如webViewDidStartLoad之类的委托方法?那是行不通的,因为他们只被解雇了一次。当导航到另一个页面时,它们不会再次被触发。
  • 不,URLProtocol
  • 很难实现。你能告诉我如何/指向正确的方向吗?
  • 好的,请稍等

标签: ios swift url uiwebview single-page-application


【解决方案1】:

第 1 步:创建自定义 URLProtocol 以捕获数据请求

class CustomURLProtocol: URLProtocol, URLSessionDataDelegate, URLSessionTaskDelegate {

    // If this returns false, the first request will basically stops at where it begins.
    override class func canInit(with request: URLRequest) -> Bool {
        return true
    }

    override class func canonicalRequest(for request: URLRequest) -> URLRequest {
        return request
    }

    override func startLoading() {

        print(self.request.url) // URL of Data requests made by UIWebView before loading.  
        URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil).dataTask(with: self.request).resume()
    }

    override func stopLoading() {

    }

    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {

        // Data request responses received.  
        self.client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .allowed)
        completionHandler(.allow)
    }

    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {

        // Data request data received.
        self.client?.urlProtocol(self, didLoad: data)
        self.urlSession(session, task: dataTask, didCompleteWithError: nil)
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {

        if let error = error {

            self.client?.urlProtocol(self, didFailWithError: error)
            return
        }

        print(self.request.url) // URL of Data requests completed.
        self.client?.urlProtocolDidFinishLoading(self)
    }
}

第 2 步:注册您的自定义 URLProtocol

在 UIWebview 中加载您的 SPA 之前注册您的自定义 URLProtocol。

URLProtocol.registerClass(CustomURLProtocol.self)

希望这会有所帮助!抱歉耽搁了,因为工作忙。

【讨论】:

  • 感谢您的回答。我在 AppDelegate 的 didFinishLaunching 方法中注册了自定义协议。我现在可以看到请求和网址!但是,网络视图不再显示加载页面。
  • 可以分享SPA网站的网址吗?我也许能帮上忙。
  • 我设法让网站加载,但遗憾的是在导航期间没有在网站内发出额外的数据请求。抱歉,我帮不上什么忙。
  • 嗯,太糟糕了。还是谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
  • 2012-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-02
  • 1970-01-01
相关资源
最近更新 更多