Reputation: 18224
I have a WKWebView, but when I click on a link that has the following URL:
blob:https://www.mycase.com/2963c6c0-24c1-418f-a314-88f7a2dbc713
Nothing happens. Reading the documentation it describes:
The only way to read content from a Blob is to use a FileReader.
So I presume there is no way WKWebView
is able to read the Blob itself by some method. As URLSession
fails to download the content when you feed it the blob URL.
A solution I came up with myself is to read the blob in JavaScript itself.
var script = ""
script = script + "var xhr = new XMLHttpRequest();"
script = script + "xhr.open('GET', '\(navigationURL)', true);"
script = script + "xhr.responseType = 'blob';"
script = script + "xhr.onload = function(e) { if (this.status == 200) { var blob = this.response; 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, completionHandler: nil);
Then add a script message handler to fetch the content.
let configuration = WKWebViewConfiguration()
configuration.userContentController.add(self, name: "readBlob")
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print(message.body)
}
It feels a bit cumbersome to do it like this, is there any other way?
Upvotes: 30
Views: 7290
Reputation: 3897
an alternative
Using fetch()
instead of XMLHttpRequest
, since fetch() API is more modern and might provide cleaner syntax for handling blobs.
const url = navigationURL;
fetch(url)
.then(response => response.blob())
.then(blob => {
const reader = new FileReader();
reader.onload = () => {
window.webkit.messageHandlers.readBlob.postMessage(reader.result);
};
reader.readAsDataURL(blob);
})
.catch(e => console.error(e));
One more alternative is considerind encoding it in Base64, which might be more robust for handling in your native code.
Having said the above your solution is still quite good to be sincere.
Upvotes: 1