WKWebView в iOS-приложении загружается очень долго - PullRequest
0 голосов
/ 26 мая 2018

У меня есть UIView, который имеет WKWebView в качестве подпредставления.С веб-представлением все в порядке, но отображение HTML-документа занимает много времени (более секунды).Документ представляет собой локальный файл (файл HTML в проекте), поэтому задержка Интернета отсутствует, и это относительно простой документ HTML.HTML-документ содержит восемь небольших изображений, но есть аналогичная проблема с другим HTML-документом, в котором нет изображений.

Вот код, который загружает HTML-документ в веб-представление:

override func viewDidLoad() {
    super.viewDidLoad()
    let localHtmlFile = Bundle.main.url(forResource: "place", withExtension: "html");
    let request = URLRequest(url: localHtmlFile!);
    webView.load(request);
}

Я использую Xcode 9.3, Swift 4.1 и iOS 11.2.

Задержка происходит каждый раз, когда я захожу на этот экран.Если невозможно предотвратить задержку в первый раз, возможно ли сохранить веб-представление таким образом, чтобы задержка происходила только один раз?

Ответы [ 2 ]

0 голосов
/ 14 июня 2018

Очевидно, что задержка вызвана временем, которое требуется для создания нового экземпляра WKWebView, а не временем, которое требуется для загрузки документа HTML.Чтобы избежать этой задержки, я нашел способ повторно использовать веб-представление.

Сначала я удалил веб-представление из сцены раскадровки, чтобы новое веб-представление не создавалось при каждой загрузке представления.Я создал общий вид с именем container, который соответствует размеру, который я хотел видеть в Интернете.

Затем я создал статическую переменную, чтобы сохранить указатель на веб-представление:
static var webView: WKWebView? = nil
В моем случае эта статическая переменная находится в классе с именем GameController.

Затем я изменил код, чтобы проверить, равна ли статическая переменная webView нулю.Если webView равно nil, код создает новое веб-представление и устанавливает статическую переменную, указывающую на это веб-представление.Затем код программно добавляет веб-представление как подпредставление контейнера в сцене раскадровки.

Чтобы настроить раскадровку и написать этот код, я использовал объяснение на следующем веб-сайте:
http://www.onebigfunction.com/ios/2016/12/14/iOS-javascript-communication/

Основной код в контроллере вида для сценыкоторый использует веб-представление (WebViewController в моем коде) выглядит следующим образом:

override func loadView() {
    super.loadView()
    if GameController.webView == nil {
        var webFrame = self.container!.frame
        webFrame.origin.x = 0
        webFrame.origin.y = 0
        let config = WKWebViewConfiguration()
        webView = WKWebView(frame: webFrame,
                            configuration: config)
        GameController.webView = webView
    } else {
        webView = GameController.webView
    }
    self.container!.addSubview(webView)
}

В моем случае я хотел отправить информацию из кода JavaScript в веб-представлении в код Swift в моем приложении, поэтомуМне пришлось больше работать с конфигурациями.Я также хотел, чтобы веб-представление было прозрачным, поэтому я добавил для этого заявление.

override func loadView() {
    super.loadView()
    if GameController.webView == nil {
        var webFrame = self.container!.frame
        webFrame.origin.x = 0
        webFrame.origin.y = 0
        let config = WKWebViewConfiguration()
        config.userContentController.add(self, name: "scriptHandler")
        webView = WKWebView(frame: webFrame,
                            configuration: config)
        webView.isOpaque = false
        GameController.webView = webView
    } else {
        webView = GameController.webView
        webView.configuration.userContentController.removeScriptMessageHandler(
            forName: "scriptHandler")
        webView.configuration.userContentController.add(self,
             name: "scriptHandler")
    }
    self.container!.addSubview(webView)
}

Первоначально я устанавливал обработчик сценария только при первом просмотре веб-страницы, но это не сработало.По-видимому, каждый раз при загрузке сцены создавался новый объект контроллера представления, поэтому старый обработчик сценариев не работал.Этот код удаляет обработчик сценария, который указывает на старый контроллер представления, и добавляет обработчик сценария, который указывает на новый контроллер представления.

0 голосов
/ 26 мая 2018

Просто сохраните ссылку на ViewController, возможно, в родительском контроллере, делегате приложения или даже в singleton / global.Это должно быть несколько быстрее при последующих нагрузках.

...