capacitor icon indicating copy to clipboard operation
capacitor copied to clipboard

Introduce blob handling for Android & iOS πŸš€πŸš€

Open gwdp opened this issue 2 years ago β€’ 16 comments

Introduce blob handling for Android & iOS webviews πŸš€πŸš€

Whenever is asked for blob:/ or normal downloads to be 'opened', folder selection is prompted and file saved.

This closes #5478

Test cases are addressed on the following repo: https://github.com/ikon-integration/Capacitor-Blob-Download-Issue


To summarize, there are 4 common download cases that could be addressed:

  • Base64 blobs through blob:data... scheme.
    • Expanding this for 2 cases, known mime-types and unknown mime-types.
    • Both Android and iOS were opening png on the internal browser (as an example). This causes users to be stuck on the image and manual closure of the application is needed.
  • Blob links though blob:http... scheme.
  • Web worker initiated downloads.

All test cases are shown on the example repo above. However, I was able to address only the first 3 on this PR. Web worker initiated downloads are probably handled by the browser core and my bet is that we won't have access to those APIs.


Approaches:

iOS

Pretty simple, it does only work on iOS 14.5 >=, as WebKit has exposed APIs for handling such only since. When a download request is received, we prompt for folder selection and then save the file with a unique file name.

Android

LIttle more complex, had to implement JS interface that injects JS code to download the received URL through XHR (so it does use the JS accessible context), pipe that in chunks to an Intent that asks the user for a file selection and then pipe the received content to a file with a 'duplex' stream implementation.

Commonly

Both approaches ask users for destination selection and implement download notifications to be later consumed by App plugin (so applications can decide what to do with it (show alert, show it on a list, or whatever)).


Still, not sure if the implementation is 100% correct but it does work with all the 3 test cases specified above and does not break anything AFAIK. So, maybe is just a matter of consolidating it a little more. Review and suggestions and highly appreciated :)

gwdp avatar Mar 12 '22 01:03 gwdp

This is amazing ! thanks for that

riderx avatar Mar 25 '22 17:03 riderx

I wish I could implement this as a plugin, but mostly sure I won't have access to or overwrite the things I need. Change is almost a month old and crickets are chirping.. :/ This is just sad.

gwdp avatar Apr 05 '22 23:04 gwdp

I wish I could implement this as a plugin, but mostly sure I won't have access to or overwrite the things I need. Change is almost a month old and crickets are chirping.. :/ This is just sad.

Sorry for the delay in any response, I've enabled the CI checks and there appears to be a lint issue. Please correct this and I will continue to review.

In the mean while I'm trying out the tests for myself. Thanks for contributing!

Dan GiraltΓ© - Lead Engineer Capacitor & Portals @ Ionic

giralte-ionic avatar Apr 07 '22 18:04 giralte-ionic

@giralte-ionic appreciate your reply and time on it. Lint issues fixed and rebased. Let me know if you need any other changes.

gwdp avatar Apr 07 '22 22:04 gwdp

Fixed iOS test

gwdp avatar Apr 08 '22 16:04 gwdp

Fixed Xcode 12.4< errors. Just not 100% sure about:

// TODO: remove once Xcode 12 support is dropped
#if compiler(<5.5)
    protocol WKDownloadDelegate {}
#endif

It does work (not sure if the best approach). :)

gwdp avatar Apr 08 '22 17:04 gwdp

Sorry it's been taking some time but I've moved this up to the rest of the capacitor team for review. Things are moving forward. More soon.

giralte-ionic avatar May 06 '22 14:05 giralte-ionic

I'm sorry @giralte-ionic , but this is looking ridiculous now. Almost 3 months old and not even a code review.

gwdp avatar Jun 02 '22 16:06 gwdp

@gwdp sorry you can't see the significant work that's been put into proving this out, nor some of the controversy this PR has roused. I'm also sorry I haven't posted a newer response.

The issue we have with this change set is that it's being done to the core of Capacitor, and is better suited for the Capacitor Filesystem Plugin.

giralte-ionic avatar Jun 02 '22 16:06 giralte-ionic

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

rowrowrowrow avatar Nov 24 '22 19:11 rowrowrowrow

@gwdp Can you update this PR against the latest so I can test?

I did a quick test for iOS. I tried copying the the full file contents for iOS from the PR. I found that it successfully loaded a separate interface upon clicking a blob url link like 'blob:capacitor://localhost/...' but from what I could tell something stopped there. In the logs I saw the "Downloading File" message and that's the last of it. Figure my version of capacitor, mismatched with this PR or something else needs addressing, let me know.

rowrowrowrow avatar Nov 24 '22 19:11 rowrowrowrow

Any news on this PR?

petrot avatar Feb 28 '23 16:02 petrot

Hi all! We never got traction on this from the Ionic team. For that reason, unfortunately, I'm not rebasing on making any additional effort towards it until we can have some of the code reviewed by the team. Really unlucky on this as it would bring a nice set of features to the framework besides not impacting any additional functionality. Not sure what happened here; guessing a conflict of interest. ✌️

gwdp avatar Mar 15 '23 18:03 gwdp

@giralte-ionic Having an anchor tag with a blob these days is expected behavior. Please merge this commit, this is functionality that should be available out of the box.

seemsindie avatar Oct 03 '23 18:10 seemsindie

Hello,

Can we get an update on this matter ?

Thanks

maximevast avatar Mar 15 '24 13:03 maximevast

@giralte-ionic could we somehow push this forward?

marcomaranao avatar Apr 04 '24 02:04 marcomaranao