The first issue is the entitlement. I've added the following entitlement: (https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_files_all )
com.apple.security.files.all (which is deprecated according to the doc)
com.apple.security.files.user-selected.read-write
com.apple.security.files.downloads.read-write
The second issue is the privacy settings.
The first time when I run it, the dialog asking for permissions will pop up, which is fine. But if I delete the app and download it again from the Internet (e.g. Google Drive) for simulating the reinstalling procedure in the Downloads/ folder, the error mentioned above will appear again.
Here're what I've tried yet none of them worked:
Allow apps downloaded from "Anywhere" in the "Security & Privacy" setting;
Grant "Full Disk Access" to the app;
Change it to read&write for everyone in "Get Info".
Any help with all these? Thanks a lot in advance!
That’s fine. macOS’s file system permissions model applies to all apps regardless of how the app was built. Sometimes you run into issues because your third-party tool constructs the app weirdly (yes, I’m looking at you Java!) but there’s nothing about Xcode that makes it fundamentally special.I didn't use Xcode. The app is built directly from Unity.
No. The key issue regarding app distribution is quarantine. When you download an app using Safari it quarantines it. When you launch a quarantined app, the system invokes Gatekeeper. See the Safely open apps on your Mac (from Apple Support) for more about this technology.is sharing the .app through Google Drive link regarded as "Software
distribution outside the Mac App Store"?
Quarantine in an opt-in system; the app doing the download controls whether something is quarantine. I don’t use Google Drive so I don’t know if it applies quarantine. It’s easy to check in Terminal though:
Code Block % xattr /path/to/your.app
If this lists a com.apple.quarantine attribute, the app is quarantined.
If you user runs a quarantined app then one of two things happens:
If the app comes from the Mac App Store then Gatekeeper… actually, I’m not 100% sure what the process is in this case but it doesn’t matter to you so let’s move on.
If the app is distributed independently, it must be signed with a Developer ID signing identity and also notarised.
Fortunately that seems like the case here because, if Gatekeeper were blocking your app, you’d get a big alert telling you that, not a file system permissions problem.
This is your fundamental problem. Mac apps simply don’t work this way. Consider what happens for a normal app, installed in the Applications directory:Also it needs to read a data file, which is exactly in the same folder
where the app is located.
User A logs in.
And configures your app by modifying /Applications/DataToBeRead.txt.
And then logs out.
Now user B logs in.
Whoops, they have user A’s configuration.
Mac apps are required to store their configuration elsewhere. Exactly how you do that depends on the specifics of your app. Before I go into details, however, I want to point you to my On File System Permissions post. I’m going to use a lot of terms from that post, so read it through first.
The reason why this fails in your specific case is that the Downloads directory is subject to MAC. So, if the app is in the Downloads directory and it tries to read DataToBeRead.txt from there, MAC kicks in and blocks the read.
The solution isn’t to try and get around MAC but rather to put the configuration file in a place that’s more in line with platform norms. How you do that depends on your target users:
If this is just a quick hack with a limited number of users, store the file in the Application Support directory (or a directory that you create within that directory) and then tell your users how to locate that.
If you plan to deploy this to a wider audience then things get more complex. I recommend that you adopt one of the two Mac app paradigms, namely, build a document-based app (think TextEdit) or a shoebox app (think Photos). In a document-based app the user is in complete control over where documents are saved. In a shoebox app you choose a default location (like the Application Support directory) and then, optionally, let the user override that. To see what I mean, look at the UI you get when you launch Photos while holding down the Option key.
A few more notes…
Don’t hard code paths. Rather, use FileManager to locate these various directories. For example, this code:
Code Block let appSupportDir = try FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true) print(appSupportDir.path) // -> /Users/quinn/Library/Application Support
The Finder hides ~/Library by default. If you want to access it, choose Go > Go to Folder and enter ~/Library.
The locations you get back from FileManager depend on whether your app is sandboxed. The above example was for a non-sandboxed app. If it were sandboxed the last line would look something like this:
Code Block // -> /Users/quinn/Library/Containers/com.example.apple-samplecode.MySandboxedApp/Data/Library/Application Support
Sandboxed apps are not allowed to access standard locations (like ~/Library/Application Support) without express user permission, so File Manager redirects all such references to within the app’s container.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"