According to Apple's documentation, for an app to access the file system outside of its container, and outside of the directories listed here, it needs to specify a File Access Temporary Exceptions Entitlement.
My app needs to read and write some files in ~/Library/Application Support/
, so I set the com.apple.security.temporary-exception.files.home-relative-path.read-write
value to /Library/Application Support/
in the app's .entitlement
plist.
Now my app is able to read files from ~/Library/Application Support/
if the path is hardcoded like this:
let filePath = URL(fileURLWithPath: "/Users/myUsername/Library/Application Support/path/to/somefile.txt")
let fileContent = try! String(contentsOf: filePath, encoding: .ascii)
However, if I do it like the following, it wouldn't work:
let filePathString = "~/Library/Application Support/path/to/somefile.txt"
let expandedFilePathString = NSString(string: filePathString).expandingTildeInPath
let filePath = URL(fileURLWithPath: expandedFilePathString)
let fileContent = try! String(contentsOf: filePath, encoding: .ascii) // Error
// alternatively
let applicationSupportPath = try! FileManager.default.url(
for: .applicationSupportDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: false
)
let filePath = applicationSupportPath.appendingPathComponent("path/to/somefile.txt")
let fileContent = try! String(contentsOf: filePath, encoding: .ascii) // Error
Both errors are because the app is trying to access a path in the container: Error Domain=NSCocoaErrorDomain Code=260 "The file “somefile.txt” couldn’t be opened because there is no such file." UserInfo={NSFilePath=/Users/myUsername/Library/Containers/my.bundle.id/Data/Library/Application Support/path/to/somefile.txt, NSUnderlyingError=0x600000c71c20 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
.
In addition, FileManager.default.homeDirectoryForCurrentUser
returns /Users/myUsername/Library/Containers/my.bundle.id/Data/
.
My question: How do I grant my app access to file system outside of its container, without hard-coding the path?
My previous quesion on the same topic has been marked as a duplicate of this question. However, the "duplicated" question is about hard-coded paths, whereas my question is about non-hard-coded paths. Also, the "duplicated" question is in Objective-C, whereas my question is in Swift.