Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: Blob downloads don't work on iOS & Android #5478

Open
gwdp opened this issue Mar 2, 2022 · 12 comments · May be fixed by #5498
Open

bug: Blob downloads don't work on iOS & Android #5478

gwdp opened this issue Mar 2, 2022 · 12 comments · May be fixed by #5498

Comments

@gwdp
Copy link

gwdp commented Mar 2, 2022

Bug Report

Capacitor Version

Latest Dependencies:

  @capacitor/cli: 3.4.1
  @capacitor/core: 3.4.1
  @capacitor/android: 3.4.1
  @capacitor/ios: 3.4.1

Installed Dependencies:

  @capacitor/cli: 3.4.1
  @capacitor/core: 3.4.1
  @capacitor/android: 3.4.1
  @capacitor/ios: 3.4.1

[success] iOS looking great! 👌
[success] Android looking great! 👌

Platform(s)

  • iOS (Tested on iOS 13.x, 14.x and 15.2 )
  • Android (tested on Android 11, API 29)

Current Behavior

iOS 15>= (tested on few 15.x different versions)
Whenever browser is asked to navigate to a URL such as blob:capacitor://localhost/ee26ec26-911c-461e-b01e-dd715c99e54a something like:

XX XXXX V1.1[59585:3775699] [Process] 0x15684b018 - [pageProxyID=5, webPageID=6, PID=59586] WebPageProxy::didFailProvisionalLoadForFrame: frameID = 3, domain = WebKitErrorDomain, code = 102

is printed out and nothing happens.

iOS 13.2.2, 13.0, 14.0.1 & 14.5 - (safe to assume this for 14.5 =<)
Error is different:

Failed to open URL blob:https://jimmywarting.github.io/29dbf607-c3d4-49a3-baa2-977d71cb3b80: Error Domain=NSOSStatusErrorDomain Code=-10814 "(null)" UserInfo={_LSLine=247, _LSFunction=-[_LSDOpenClient openURL:options:completionHandler:]}

Android
Nothing happens, more investigation is needed to see technical details of the implementation.

Expected Behavior

Allow that blob to be downloaded without errors into a standard download directory (as Safari does).
Maybe, an even better solution would be asking the user where to save it. (optionally)
By RFC these URLs should be handled and downloaded by the browser. More details at: https://w3c.github.io/FileAPI/#url-intro

Code Reproduction

iOS

  • Download from repo and install deps: https://github.com/ikon-integration/Capacitor-Blob-Download-Issue
  • Open on Xcode npx capacitor open ios, run from there
  • After the app is loaded, click on the start button. (careful, button on this sample seems pretty small on the simulator, so better to zoom on the webview)
  • Error should be printed on the console

Alternatively: (with any Capacitor app you might have around)

  • Set your capacitor.config.json server.url to https://jimmywarting.github.io/StreamSaver.js/examples/saving-multiple-files.html (example)
  • Zoom in to be able to see the start button, and click on it.
  • Error should be available on the console

Android
Same from iOS, however, no error is displayed and the file is not visible anywhere else on the system.

Other Technical Details

iOS
I believe this is not related to any versioning-related problem as it seems iOS 15 significantly improved the support of download/blob on the WKWebViewDelegate.
With some tweaks on the WebViewDelegationHandler, I was able to make it work and download to the downloads or documents folder seamlessly.

Android
Still, more investigation is needed on the Android side, but RFC described behaviour should also be

Additional Context

By RCF blob: URL schema should trigger the download of the URL being provided. I believe this will enhance Capacitor support to already existing apps as developers expect the same behaviour to be followed.

Possible fix

Changes on theWebViewDelegationHandler like the one below will handle it for iOS > 14.5, however still unsure where it should be saved as a default and how to allow developers to overwrite this behaviour. Another important factor is the attempt of making it to work with previous iOS versions for sure.
Creating a PR soon and linking into this issue. (Changes will be certainly be needed)

    ...minor changes above...
    public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        // post a notification for any listeners
        NotificationCenter.default.post(name: .capacitorDecidePolicyForNavigationAction, object: navigationAction)
        
        if #available(iOS 14.5, *) {
            if (navigationAction.shouldPerformDownload) {
                print("Is download");
                decisionHandler(.download)
                return;
            }
        }
       .....
    }
    @available(iOS 14.5, *)
    func webView(_ webView: WKWebView, navigationAction: WKNavigationAction, didBecome download: WKDownload) {
        download.delegate = self;
    }
    @available(iOS 14.5, *)
    func webView(_ webView: WKWebView, navigationResponse: WKNavigationResponse, didBecome download: WKDownload) {
        download.delegate = self;
    }

    public func download(_ download: WKDownload, decideDestinationUsing response: URLResponse, suggestedFilename: String, completionHandler: @escaping (URL?) -> Void) {
        print("decide destination", suggestedFilename);
        
        let documentsURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        let documentURL = documentsURL.appendingPathComponent(suggestedFilename, isDirectory: false)
        print(documentURL.absoluteString)
        completionHandler(documentURL);
    }
    ....minor changes below....

Edited to Improve issue with reproducible code, android behaviour and other small improvements

@gwdp gwdp changed the title bug: Blob downloads don't work on iOS bug: Blob downloads don't work on iOS & Android Mar 2, 2022
@gwdp gwdp linked a pull request Mar 12, 2022 that will close this issue
@gwdp

This comment was marked as abuse.

@marcelklehr
Copy link

Same issue here

marcelklehr added a commit to floccusaddon/floccus that referenced this issue Mar 19, 2022
@rowrowrowrow
Copy link

rowrowrowrow commented Nov 24, 2022

bump, I'm not sure if the PR for this works entirely but this functionality is necessary and expected out of the box

@giuseppeilromano
Copy link

In the console on Android I see this error: Not allowed to load local resource: blob:https://

@SergioSuarezDev
Copy link

same here

@c12i
Copy link

c12i commented Apr 27, 2023

Also experiencing the same error when attempting to download a file from a data url data:image/png;base64

@SergioSuarezDev
Copy link

1 year after, and the problem is not solved :(

@atrujillofalcon
Copy link

Same error on iOS

@kalanda
Copy link

kalanda commented May 24, 2023

Is there any solution?

@reinos
Copy link

reinos commented Sep 22, 2023

Any update on this?

1 similar comment
@seemsindie
Copy link

Any update on this?

@gwdp
Copy link
Author

gwdp commented Oct 3, 2023

Please, see #5498 (comment) for the latest info on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants