lypw2009
lypw2009

Reputation: 221

Is it possible to save WKWebview content for offline reading?

I need to save the content loaded on the WKWebView for offline reading including images. Then the users can view the web page again even there is no network access.

Does WKWebView support caching it? How can I implement it?

The answer in "UIWebView webpage caching for offline viewing" is for UIWebview not for WKWebView, so they are different. And I also know we can enable app cache for WKWebViewCache but it will use private API which will be rejected.

Upvotes: 7

Views: 4718

Answers (2)

Vivek Kumar
Vivek Kumar

Reputation: 406

//To get image from html you need to implement like this 
import UIKit
import WebKit
import SwiftSoup
import AlamofireImage


class ViewController: UIViewController, WKNavigationDelegate {
    @IBOutlet weak var webView: WKWebView!
    @IBOutlet weak var imageView: UIImageView!

    let url = URL(string: "https://www.google.com")
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        webView.navigationDelegate = self

        let urlReq = URLRequest(url: url!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 1)
        webView!.load(urlReq)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        webView.evaluateJavaScript("document.documentElement.outerHTML.toString()",
                                   completionHandler: { (html: Any?, error: Error?) in
                                    do{
                                        let doc: Document = try SwiftSoup.parse(html as! String)
                                        let pngs: Elements = try doc.select("img[src$=.png]")
                                        let srcsStringArray: [String?] = pngs.array().map { try? $0.attr("src").description }
                                        for imgs in srcsStringArray {
                                            if let imgUrl = imgs {
                                                var finalUrl = URL(string: "")
                                                if imgUrl.contains("http") {
                                                    finalUrl = URL(string: String(format: imgUrl))
                                                } else {
                                                    finalUrl = URL(string: String(format: "%@%@", (self.url?.absoluteString)!, imgUrl))
                                                }
                                                self.imageView.af_setImage(withURL: finalUrl!)
                                                print(finalUrl) //debug URL
                                            }
                                        }
                                    } catch Exception.Error(let type, let message){
                                        print(type, message)
                                    } catch {
                                        print("error")
                                    }
        })
    }
}

Upvotes: 0

Vivek Kumar
Vivek Kumar

Reputation: 406

 //Two ways i know so far
//1st : after loading the page when user is online,get the html from WKWebView as follows :




webView.evaluateJavaScript("document.documentElement.outerHTML.toString()", 
                           completionHandler: { (html: Any?, error: Error?) in
    print(html)
})




//Second way is that inject script to get html from WKWebView as follows>

 let script = WKUserScript(source: javascriptString, injectionTime: injectionTime, forMainFrameOnly: true)
userContentController.addUserScript(script)
self.webView.configuration.userContentController.addScriptMessageHandler(self, name: "didGetHTML")
func userContentController(userContentController: WKUserContentController,
        didReceiveScriptMessage message: WKScriptMessage) { if message.name == "didGetHTML" {
            if let html = message.body as? String {
                print(html)
            }
        }
}

Upvotes: 2

Related Questions