AUv3: Unable to read .txt file in Library/Containers

I’m attempting to read a .txt file I created in my app’s library container folder (~/Library/Containers/), but std::ifstream and juce::File fail to read the file.

I assume this is because of permissions for a sandboxed AUv3, so I was curious if there was a way to allow access to the ~/Library/Containers/ folder. If that is not possible, is there a place that would be fine to put a license file under? I’m not too keen about just dropping that into the Downloads folder, but macOS is starting to make me do strange things.

Thank you!

I thought the container was supposed to represent the Library folder for your application. Have you tried just accessing ~/Library? You would use the static File getSpecialLocation method:
https://docs.juce.com/develop/classFile.html#a3e19cafabb03c5838160263a6e76313d

License files on Mac (I believe) should go in (~)/Library/Application Support/Manufacturer/Application

Hope that works, I don’t have much knowledge about Mac sandboxing but it probably works better if you ignore it?..

Thank you for responding so quickly! I didn’t know about that getSpecialLocation function, that’s definitely useful going into the future.

So one problem I’m having is that I can’t even save a file to ~/Library directly, nor ~/Library/Application Support/Manufacturer/Application. It is possible that std::ifstream just doesn’t like “~” though.

The other problem is that, while I’d rather not use Mac sandboxing (or MacOS, for that matter), I need this AUv3 to run on DAWs like Garageband, and I don’t think Garageband likes non-sandboxed plugins.

Thank you again for giving it some thought, though! I was this close to releasing my plug-in tonight, but Apple, as usual, has other plans.

I also realized I neglected some information. This is on Mac OS (specifically Sonoma). I also am able to read and write to this same location (L"/Users/{me}/Library/Containers/com.XYZ.Artivox/Data/XYZ/Artivox/valid.art") with the Standalone app, it is only the AUv3 that is having a problem. I also found out that the “~/Library/Containers/” folder is created specifically by the sandbox from this link (Accessing files from the macOS App Sandbox | Apple Developer Documentation), namely:

When your sandboxed app launches for the first time, macOS creates a sandbox container on the filesystem (in ~/Library/Containers) and associates it with your app. Your app has full read and write access to its sandbox container, and can run programs located there as well.

So maybe the problem is that I need to share security groups? This is starting to go wayyy over my head, for something that is at the very tail end of a project. If anyone has any insight, I would greatly appreciate some help just to get over this final bump!

you don’t need security groups on macos for this.

first, if you have app sandboxing enabled you’ll have to set File Access: Music Folder Read/Write in projucer to allow this to work.

then you can do something like this:

// on macos this is ~/Library/Audio/Presets/JucePlugin_Manufacturer/JucePlugin_Name

juce::File Locations::userBase() {
  return juce::File::getSpecialLocation(juce::File::userHomeDirectory)
      .getChildFile("Library")
      .getChildFile("Audio")
      .getLinkedTarget()
      .getChildFile("Presets")
      .getChildFile(JucePlugin_Manufacturer)
      .getChildFile(JucePlugin_Name);
}

and when you call userBase().getChildFile("foo.txt") it comes back with a path that will work (it will be a symlink into the actual ~/Library/Audio/Presets/... directory but with a different name).

2 Likes

I’ll just add that in general t’s better to think of ~ as a shell shortcut for use in terminal. In some other places you could use the environment variable ‘HOME’ but, as above, in JUCE you use getSpecialLocation.

1 Like

Ah, thank you @modosc and @AdamVenn! The ~/Library/Audio/Presets does work for me with the updated sandbox permissions, and it’s good to know I should treat “~” as a shortcut (kind of %LocalAppData%). Now to promptly never look at macOS again lol. Thank you for the help, I really appreciate it!