Swift Загрузить сайт для очистки кода без загрузки Просмотр | WebKit - PullRequest
0 голосов
/ 10 апреля 2020

У меня есть массив URL-адресов статей в Новостях Google. URL-адрес статьи в Новостях Google немедленно перенаправляет на реальные URL, ie: CNB C .com / .... Я пытаюсь извлечь реальный перенаправленный URL-адрес. Я думал, что смогу l oop просмотреть список и загрузить ссылку на Новости Google в WebView, а затем через 1 секунду вызвать webView.url в DispatchQueue, чтобы получить реальный URL, но это не работает.

Как можно быстро получить список перенаправленных URL-адресов?

Вот мой код, который можно использовать для воспроизведения проблемы:

        let webView = WKWebView()
        let myList = [URL(string: "https://news.google.com/articles/CAIiEDthIxbgofssGWTpXgeJXzwqGQgEKhAIACoHCAow2Nb3CjDivdcCMJ_d7gU?hl=en-US&gl=US&ceid=US%3Aen"), URL(string: "https://news.google.com/articles/CAIiEP5m1nAOPt-LIA4IWMOdB3MqGQgEKhAIACoHCAowocv1CjCSptoCMPrTpgU?hl=en-US&gl=US&ceid=US%3Aen")]

        for url in myList {
            guard let link = url else {continue}
            self.webView.loadUrl(string: link.absoluteString)

            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                let redirectedLink = self.webView.url
                print("HERE redirected url: ", redirectedLink) // this does not work
            }
        }

1 Ответ

1 голос
/ 17 апреля 2020

С вашей попыткой связаны две проблемы:

1) Вы используете одно и то же веб-представление в l oop, и, поскольку в блоках l oop ничего нет, пока веб-представление не имеет Закончив загрузку, вы просто отменяете предыдущий запрос при каждом проходе l oop.

2) Даже если вы заблокировали внутри l oop, доступ к URL через секунду не будет работать надежно поскольку навигация может легко занять больше времени, чем это.

Что я бы порекомендовал сделать, так это продолжать использовать одно веб-представление (для экономии ресурсов), но использовать его интерфейс делегирования навигации для разрешения URL-адресов по одному one .

Это грубый пример, чтобы дать вам основную c идею:

import UIKit
import WebKit

@objc class RedirectResolver: NSObject, WKNavigationDelegate {

    private var urls: [URL]
    private var resolvedURLs = [URL]()
    private let completion: ([URL]) -> Void
    private let webView = WKWebView()

    init(urls: [URL], completion: @escaping ([URL]) -> Void) {
        self.urls = urls
        self.completion = completion
        super.init()
        webView.navigationDelegate = self
    }

    func start() {
        resolveNext()
    }

    private func resolveNext() {
        guard let url = urls.popLast() else {
            completion(resolvedURLs)
            return
        }
        let request = URLRequest(url: url)
        webView.load(request)
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        resolvedURLs.append(webView.url!)
        resolveNext()
    }

}


class ViewController: UIViewController {

    private var resolver: RedirectResolver!

    override func viewDidLoad() {
        super.viewDidLoad()

        resolver = RedirectResolver(
            urls: [URL(string: "https://news.google.com/articles/CAIiEDthIxbgofssGWTpXgeJXzwqGQgEKhAIACoHCAow2Nb3CjDivdcCMJ_d7gU?hl=en-US&gl=US&ceid=US%3Aen")!, URL(string: "https://news.google.com/articles/CAIiEP5m1nAOPt-LIA4IWMOdB3MqGQgEKhAIACoHCAowocv1CjCSptoCMPrTpgU?hl=en-US&gl=US&ceid=US%3Aen")!],
            completion: { urls in
                print(urls)
            })
        resolver.start()
    }

}

Это выводит следующие разрешенные URL:

[https://amp.cnn.com/cnn/2020/04/09/politics/trump-coronavirus-tests/index.html, https://www.cnbc.com/amp/2020/04/10/asia-markets-coronavirus-china-inflation-data-currencies-in-focus.html]

Еще одна вещь, на которую следует обратить внимание, заключается в том, что перенаправление этих URL, в частности, зависит от JavaScript, что означает, что вам действительно нужен веб-просмотр. В противном случае было бы достаточно набрать URLRequest s вручную и наблюдать за ответами.

...