WKWebViewDownloadHelper icon indicating copy to clipboard operation
WKWebViewDownloadHelper copied to clipboard

iOS 14.5 downloader works with a blob but fallback code does not

Open tsouthen opened this issue 3 years ago • 2 comments

Thanks very much for the great code example!

I'm experiencing a problem downloading blob data. Using the new iOS 14.5 API works fine, but if I comment that out and try the fallback downloadData function it doesn't download all the data. Everything seems to work (no errors) but it only downloads about 3KB instead of 64KB.

Note: I tried this in both my own project and in your sample project. I also made sure the blob: prefix was removed from the URL.

Any idea why the downloadData function doesn't work? I really don't want my app to require iOS 14.5.

tsouthen avatar Sep 15 '21 05:09 tsouthen

Do you have a test URL to download the blob?

gualtierofrigerio avatar Sep 15 '21 12:09 gualtierofrigerio

I'm using this website: Health Gateway. Unfortunately, it requires entering personal information that I can't share.

I've managed to work around it all by converting the blob URL to a data URL in javascript and then when that data is received I send it back to my app.

        func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
            // from https://stackoverflow.com/a/16179887/453479
            let blobToDataUrlJs = """
                var xhr = new XMLHttpRequest;
                xhr.responseType = 'blob';
                
                xhr.onload = function() {
                   var recoveredBlob = xhr.response;
                
                   var reader = new FileReader;
                
                   reader.onload = function() {
                     var blobAsDataUrl = reader.result;
                     console.log("Converted blob to data url!");
                     console.log("dataUrl:" + blobAsDataUrl.substring(0, 50));
                     window.location = blobAsDataUrl;
                   };
                
                   reader.readAsDataURL(recoveredBlob);
                };
                
                xhr.open('GET', blobUrl);
                xhr.send();
                """
            if let url = navigationAction.request.url {
                if url.scheme == "data", let handler = parent.onDataReceived {
                    if let data = try? Data(contentsOf: url) {
                        handler(data)
                    }
                } else if url.scheme == "blob" {
                    print("blob navigation action")
                    webView.evaluateJavaScript("var blobUrl='\(url.absoluteString)';" + blobToDataUrlJs)
                    decisionHandler(.cancel)
                    return
                }
            }
            decisionHandler(.allow)
        }

tsouthen avatar Sep 15 '21 17:09 tsouthen