IOS - Как получить кэшированные ресурсы из WKWebView? - PullRequest
0 голосов
/ 12 июня 2018

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

Например, когда я используюWKWebView для загрузки этот URL , он отображает файл PDF, и я хочу получить этот файл PDF из WKWebView, чтобы поделиться им после полной загрузки URL

Я проверил на ChromeЕсли я захочу поделиться файлом по указанной выше ссылке, он снова запросит и загрузит контент с URL после этого отображения общего ресурса.Это означает, что они не получают его из текущих WKWebView (кэшированных ресурсов).

Но в Safari они каким-то образом отображают диалоговое окно «Поделиться» сразу после нажатия кнопки «Поделиться» и выглядят так, как будто не загружаются снова.Я думаю, что они получают pdf-файл из кэша или где-то в WkWebView и делятся им.

Другой способ понять вопрос - Как получить файл, который представлен в WKWebView без загрузки контентаснова?

enter image description here

Если у вопроса недостаточно информации для ответа, не стесняйтесь оставлять комментарии, и я сделаю их более понятными.

1 Ответ

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

Как я знаю, кэширование для всех ресурсов, загруженных в WKWebView, установлено по умолчанию: True

Учитывая это, если вы запрашиваете тот жересурс, webview не будет загружать контент из интернета, он даст вам контент из кэшированных ресурсов.Для запроса того же ресурса вы можете использовать JavaScript для получения контента.

Посмотрите на приведенный ниже код.Как только PDF загружен, и вы нажмете кнопку «Сохранить».он выполнит код JavaScript, и когда данные будут готовы доставить с помощью JavaScript

, будет запущено window.webkit.messageHandlers.myInterface.postMessage(base64)

, чтобы ваш ViewController знал, что данные готовы для совместного использования.

Вы можете проверить то же самое с помощью

  1. Разрешить загрузку PDF

  2. Выключить интернет симулятора ( см. )

  3. Нажмите кнопку сохранения

Вы получите данные в формате PDF в формате base64.сохраните его и поделитесь им:)

    import UIKit
    import WebKit
    class ViewController: UIViewController {

        @IBOutlet weak var webView: WKWebView!
        var activityIndicator: UIActivityIndicatorView?
        override func viewDidLoad() {
            super.viewDidLoad()

        }

        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
            activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
            webView.navigationDelegate = self
            activityIndicator?.center = self.view.center
            self.view.addSubview(activityIndicator!)
            webView.configuration.userContentController.add(self, name: "myInterface")
            webView.load(URLRequest(url: URL(string: "http://www.africau.edu/images/default/sample.pdf")!))
            activityIndicator?.startAnimating()
        }

        @IBAction func saveAction(_ sender: Any) {
            let s = """
            var xhr = new XMLHttpRequest();
            xhr.open('GET', "\(webView.url?.absoluteString ?? "")", true);
            xhr.responseType = 'arraybuffer';
            xhr.onload = function(e) {
            if (this.status == 200) {
            var uInt8Array = new Uint8Array(this.response);
            var i = uInt8Array.length;
            var binaryString = new Array(i);
            while (i--){
            binaryString[i] = String.fromCharCode(uInt8Array[i]);
            }
            var data = binaryString.join('');
            var base64 = window.btoa(data);

       window.webkit.messageHandlers.myInterface.postMessage(base64);
            }
            };
            xhr.send();
            """




            webView?.evaluateJavaScript(s, completionHandler: {(string,error) in
                print(error ?? "no error")
            })
        }
    }

    extension ViewController: WKScriptMessageHandler{
      func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    //    print("Message received: \(message.name) with body: \(message.body)")

        guard
          var documentsURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last,
          let convertedData = Data.init(base64Encoded: message.body as! String)
          else {
            //handle error when getting documents URL
            return
        }

        //name your file however you prefer
        documentsURL.appendPathComponent("sample.pdf")

        do {
          try convertedData.write(to: documentsURL)
        } catch {
          //handle write error here
        }

        //if you want to get a quick output of where your
        //file was saved from the simulator on your machine
        //just print the documentsURL and go there in Finder
        print(documentsURL)

        let activityViewController = UIActivityViewController.init(activityItems: [documentsURL], applicationActivities: nil)
        present(activityViewController, animated: true, completion: nil)
      }
    }

    extension ViewController: WKNavigationDelegate{
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            self.activityIndicator?.stopAnimating()
            self.activityIndicator?.removeFromSuperview()
            self.activityIndicator = nil
        }
    }

Кстати, предоставленная вами PDF-ссылка использует HTTP, а не HTTPS.Таким образом, для целей тестирования добавьте следующее в info.plist

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoadsInWebContent</key>
        <true/>
    </dict>
...