I am accessing a website using WKWebView and on that website there is a download button. On Chrome using a laptop that downloads the file, when I click download on the iOS simulator it displays the image in the WKWebView. My goal is to save that image off and display it in a CollectionView later. If I had the URL as https://www.website.com/image.jpg
then that would be easy to do, the problem is it is a blob url so the format blob:https://www.website.com/abcd-efgh-ijkl
.
I found this link which is somewhat helpful: How to read a blob data URL in WKWebView?
Here is a slimmed down version of my ViewController:
import UIKit
import WebKit
class DownloadBlob: UIViewController, WKNavigationDelegate, WKScriptMessageHandler {
lazy var webView: WKWebView = {
let config = WKWebViewConfiguration()
config.userContentController.add(self, name: "readBlob")
let webView = WKWebView(frame: UIScreen.main.bounds, configuration: config)
webView.navigationDelegate = self
return webView
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let request = URLRequest(url: url!)
webView.load(request)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("Finished")
}
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
print(navigationResponse)
decisionHandler(.allow)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
print(navigationAction)
let navigationURL = navigationAction.request.url
if (navigationURL?.absoluteString.contains("blob"))! {
testDownloadBlob(navigationURL: navigationURL!)
}
decisionHandler(.allow)
}
func testDownloadBlob(navigationURL: URL) {
var script = ""
script = script + "var xhr = new XMLHttpRequest();"
script = script + "xhr.open('GET', '\(navigationURL.absoluteString)', true);"
script = script + "xhr.responseType = 'blob';"
script = script + "window.webkit.messageHandlers.readBlob.postMessage('making sure script called');"
script = script + "xhr.onload = function(e) { if (this.status == 200) { var blob = this.response; window.webkit.messageHandlers.readBlob.postMessage(blob); var reader = new window.FileReader(); reader.readAsBinaryString(blob); reader.onloadend = function() { window.webkit.messageHandlers.readBlob.postMessage(reader.result); }}};"
script = script + "xhr.send();"
self.webView.evaluateJavaScript(script) { (results, error) in
print(results ?? "")
}
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print(message.name, message.body)
}
}
I noticed that the xhr.onload isn't being called at all, but not sure how to fix this. I do, however, get a response with the blob in the decidePolicyFor navigationResponse.
Is there a way to do this to get the image data and save it?