Yes, I know. But if a user clicks a file in the iOS file browser (I don’t mean the JUCE native file chooser, but the separate app), there’s currently no way find get access to this file in JUCE (AFAIK).
This patch is useful if you get a file via e-mail and want to open it in your app via a simple click.
Just a status update, as you mentioned this thread from another conversation: Looking at this patch has gone into our backlog, but it’s not particularly high priority so no promises when we’ll get round to it.
second, because of how reading private files works in ios (and how this patch is implemented) this approach will not work:
void urlOpened(const juce::URL &url) override {
// get a File from the URL
juce::File file = url.getLocalFile();
// this will be false!
file.existsAsFile();
// this will fail too because the file is inaccessible
doSomething(file);
but this will work:
void urlOpened(const juce::URL &url) override {
// create an InputStream
auto input = url.createInputStream(juce::URL::InputStreamOptions(juce::URL::ParameterHandling::inAddress));
// now read from the InputStream
auto data = input.readEntireStreamAsString();
// this will be false
data.isEmpty();
// now you can do something with the data
It seems like this patch (or something implementing a similar solution) still hasn’t been applied. Is there any pointer on how to handle opening files from within iOS’ file browser?
the current version of the patch i’m using is here:
and then i have this code in StandaloneApp.cpp:
#if JucePlugin_Build_Standalone && JUCE_IOS
void urlOpened(const juce::URL &url) override {
// we have to read our url as an InputStream, otherwise
// we won't have access to the underlying bookmark data.
auto is = url.createInputStream(
juce::URL::InputStreamOptions(juce::URL::ParameterHandling::inAddress));
// so we read from the url and write to a temp file
// with the same extension.
auto tmp = juce::TemporaryFile(url.getLocalFile().getFileExtension());
auto tmpFile = tmp.getFile();
auto os = juce::FileOutputStream(tmpFile);
os.writeFromInputStream(*is, -1);
// call flush so the file is readable!
os.flush();
// and now we can do something with our tmpFile
doSomething(tmpFile);
// note that our tmpFile will be cleaned up by going out
// of scope.
}
#endif
It’s amazing to me that this still hasn’t been added to JUCE. It’s pretty much essential if you want your standalone plugin to be able to interact with the iOS Files app.
Hey @modosc@dhilowitz@PixelPacker and @leehu
Many thanks to everyone for sharing this info. With a combination of the above I managed to get this working nicely at my end too. So cool!
However, I’m a little puzzled as to why this hasn’t been rolled into JUCE proper. Is there somewhere I can vote towards getting the pull request rolled in?
An approach to this could be extending the Projucer to allow populating intent-filters via some CSV or whatever textbox option in the Android exporter.
I would say Cmake might need some TLC in this regard but I don’t think JUCE officially supports Android/Cmake right now… (correct me if I’m wrong!)
The app would then need to have a JNI interface to accept the related intents, and would then need pipe those events into the app similar to how that was done in the PR for iOS.
I agree in that there’s definitely a strong argument to have a cross-platform solution for this.
In the right here right now, how are iOS devs are handling this urlOpened situation? I’m repeatedly re-applying a patch to whatever JUCE commit I’m using via a git stash. This seems super hacky and naive. Surely there’s a better approach, right?
To avoid that I keep my own JUCE fork. I apply patches and changes to my fork and these changes persist even after syncing my fork with the current develop tip, which I do regularly. Very rarely there can be a conflict when syncing (an update to the JUCE codebase which directly overwrites one of my changes) which I need to resolve manually, but that’s it.