如何从WKWebView获取缓存的资源

如何从WKWebView获取缓存的资源

本文介绍了iOS-如何从WKWebView获取缓存的资源?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,默认情况下设置为WKWebView中加载的所有资源缓存.有几篇关于如何从WKWebView中删除缓存的资源?的帖子,但是我找不到关于如何从WKWebView获取它的任何帖子.

As I know, caching for the all resources loaded in WKWebView is set by default. There are several post about How to remove cached resources from WKWebView? but I can't find any posts about the way to get it from WKWebView.

例如,当我使用WKWebView加载此网址时,它显示一个pdf文件,我要从URL完全加载后从WKWebView获取此pdf文件以共享

For example, when I use WKWebView to load this url, it displays a pdf file and what I want is getting this pdf file from WKWebView to share after url is loaded completely

我已经在Chrome上进行了检查,如果我想从上面的链接共享文件,它将在显示共享对话框后再次请求并从url下载内容.这意味着他们不会从当前的WKWebView(缓存的资源)中获取它.

I have checked on Chrome, if I want to share the file from above link, it will request and download content from url again after that displaying share dialog. It means that they don't get it from current WKWebView (cached resources).

但是在Safari上,它们以某种方式在单击共享"按钮后立即显示共享"对话框,好像没有再次下载.我认为他们从缓存或WkWebView中的某处获取pdf文件并共享.

But on Safari, somehow they show share dialog immediately after clicking on share button and seem like without downloading again. I think they get pdf file from cache or somewhere in WkWebView and share it.

理解该问题的另一种方法是 如何在不重新下载内容的情况下获取显示在WKWebView上的文件?

Another way to understand the question is How to get a file which is presented on WKWebView without downloading content again?

如果问题没有足够的答案信息,请随时发表评论,我会更清楚.

If the question doesn't have enough information for an answer, feel free to leave a comment and I will make it clearer.

推荐答案

请记住,如果您请求相同的资源,则webview不会从Internet加载内容,而是会为您提供来自缓存资源的内容.要请求相同的资源,可以使用一些 JavaScript 来获取内容.

By keeping that in mind if you request for the same resource, webview will not load content from internet it will give you the content from the cached resources. For requesting the same resource, you can use some JavaScript to get the content.

看下面的代码.加载PDF后,您点击了保存按钮.它会执行JavaScript代码,并在准备好通过JavaScript传递数据时执行

Look at the below code. Once the PDF is loaded and you hit the save button. it will execute JavaScript Code and when the data is ready to deliver by JavaScript

它将触发window.webkit.messageHandlers.myInterface.postMessage(base64)

让您的ViewController知道可以共享数据了.

to let your ViewController know that data is ready to be shared.

您可以通过以下方式进行验证

You can verify the same by

  1. 让它加载PDF

  1. Let it load the PDF

关闭模拟器的互联网(请参见)

Turn off the simulator's internet(see)

点击保存按钮

您将获得base64格式的pdf数据.保存并共享:)

You will get your pdf data in base64 format. save it and share it :)

    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

BTW the pdf link you provided is using HTTP not HTTPS. So for testing purpose add the following in your info.plist

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

这篇关于iOS-如何从WKWebView获取缓存的资源?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 09:22