Hello:
I'm currently working on my first app which I'm looking at releasing throught the Mac App Store - but I'm not sure if what I'm trying to do is not allowed, or if I'm just being ******.
My app is a helper for another manufacturer's app, and will need to write to the other app's ~/Library/Application Support folder - so I have:
- Enabled the App Sandbox in my application target;
- Edited the entitlements file to add an array named 'com.apple.security.temporary-exception.files.home-relative-path.read-write', which in turn has a single string entry of '/Library/Application Support/'.
Yet, when I attempt to get the Application Support folder URL with
let applicationSupportURL = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first
then I get this returned: file:///Users/<username>/Library/Containers/<appBundleID>/Data/Library/Application%20Support/
(Note: once I get this working with the Application Support folder, then I'll further narrow it down to just the required folder I need.)
Attempting to get the user to select the appropriate folder via an OpenPanel (and thus address it via a security-scoped URL) is not desirable:
- It's the same folder on every system that my app addresses, so why should I have to ask for it?
- As it's in ~/Library, it's difficult to get users to reliably find that folder, considering it's usually hidden.
What am I missing?
Thanks.
First up, let’s answer your technical question. It’s true that
FileManager.urls(for:in:)
returns URLs relative to your app’s container rather than the user’s real home directory. This is generally the right thing to do, because most apps can’t access the real home directory. If you want the path to the real home directory, you’ll have to get it via other means. The approach I generally use involves
getpwuid
. For example:
func realHomeDirectory() -> URL? {
guard let pw = getpwuid(getuid()) else { return nil }
return URL(fileURLWithFileSystemRepresentation: pw.pointee.pw_dir, isDirectory: true, relativeTo: nil)
}
Next, let’s talk about App Review. To start, be aware that I don’t work for App Review, and thus I can’t make definitive statements on their behalf. However, my understanding is that App Review carefully audits any use of file access temporary exceptions. I’m skeptical that you’ll be able to convince them that your exception is justified.
You wrote:
It's the same folder on every system that my app addresses, so why should I have to ask for it?
Because the act of selecting that directory is considered to be explicit authorisation by the user for your app to access that directory. One of the key legs of Apple’s privacy stance is transparency, and implicit access like the one you’re proposing is not in any way transparent.
As it's in
, it's difficult to get users to reliably find that folder, considering it's usually hidden.~/Library
True. I think you can help with this by setting the default directory of the open panel appropriately, based on the real home directory you calculated above.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"