代码之家  ›  专栏  ›  技术社区  ›  trungduc 邱林和

iOS-如何从wkwebview获取缓存资源?

  •  5
  • trungduc 邱林和  · 技术社区  · 7 年前

    我知道,缓存加载到 WKWebView 默认设置。有好几篇关于 如何从wkwebview中删除缓存资源? 但是我找不到任何关于如何从 小精灵 .

    例如,当我使用 WKWebVIEW 载入 this url ,它显示一个pdf文件,我想要的是从 WKWebVIEW 在url完全加载后共享

    我已经检查了chrome,如果我想从上面的链接共享文件,它会在显示共享对话框后再次从url请求和下载内容。这意味着他们不能从当前 WKWebVIEW (缓存资源)。

    但在safari上,他们在点击share按钮后会立即显示share对话框,看起来好像没有再次下载。我想他们从缓存或其他地方得到pdf文件 WkWebView 分享它。

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

    enter image description here

    如果问题没有足够的信息来回答,请留下评论,我会让它更清楚。

    1 回复  |  直到 7 年前
        1
  •  2
  •   trungduc 邱林和    7 年前

    据我所知,wkwebview中加载的所有资源的缓存是由 违约:

    记住,如果您请求相同的资源,webview将不会从internet加载内容,它将从缓存的资源中为您提供内容。对于请求相同的资源,可以使用 javascript 获取内容。

    请看下面的代码。一旦加载pdf并点击save按钮。它将执行javascript代码,当数据准备好由javascript交付时

    它会燃烧 window.webkit.messageHandlers.myInterface.postMessage(base64)

    让viewcontroller知道数据已准备好共享。

    你可以通过

    1. 让它加载pdf

    2. 关闭模拟器的互联网( see )

    3. 点击保存按钮

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

        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>