How can I test whether I can read or write a directory?

102 views Asked by At

I am writing an app which will be sandboxed when I finish with it. For now it’s not.

The app will copy files from one location to another. Because it’s not currently sandboxed, I can preset the directories and go ahead.

When it’s sandboxed, I won’t be able to do that until I manually select the two locations. Without selecting the two locations, the code quietly doesn’t work.

I can’t find anything which lets me know whether I can go ahead. Is there some sort of status I can examine?

3

There are 3 answers

0
workingdog support Ukraine On

You could try something simple like this example code.

Change the File Access Type in your App Sandbox and see the changes.

struct ContentView: View {
    let path = "/Users/THE-USER/Downloads/testFile.txt"
    
    var body: some View {
        Text(path).foregroundStyle(.blue)
        Text("FREAD: \(checkFile(FREAD))")
        Text("FWRITE: \(checkFile(FWRITE))")
        Text("O_RDONLY: \(checkFile(O_RDONLY))")
        Text("O_RDWR: \(checkFile(O_RDWR))")
    }
    
    func checkFile(_ flag: Int32) -> Int32 {
        let thePath = (path as NSString)
        return open(thePath.fileSystemRepresentation, flag)
    }
}
0
Manngo On

OK, the solution is to use FileManager.default.isReadableFile(atPath: …).

Here’s a simple application of it:

struct ContentView: View {
    @State var dir: String? = "."
    @State var dirOK = false
    

    var body: some View {
        return VStack {
            Button(action: {
                dir = selectFolder(title: "Open …", directoryURL: dir ?? ".")
                dirOK = dir != nil && FileManager.default.isReadableFile(atPath: dir!)
            }) {
                Text("Open …")
            }
            Text(dir!)
            Text(dirOK ? "Ok" : "no")
        }.onAppear() {
            dirOK = dir != nil && FileManager.default.isReadableFile(atPath: dir!)
        }
    }
}           

Assume that there’s a function called selectFolder().

If the app is sandboxed, dirOK is false until you select a directory. If it’s not sandboxed, and dir refers to a valid directory, dirOK is true.

2
vadian On

There is no need to check for writing permission.

In a sandboxed environment if the locations are outside the application container it is required that the user selects the locations before accessing them.

Another requirement is that User Selected File must be set to Read/Write in the sandbox entitlements.

  1. If a location is supposed to be permanent (across application relaunch) create a security scoped bookmark and resolve it on launch. If it fails ask the user again to select the location. To be able to write into the location you have to call startAccessingSecurityScopedResource() and stopAccessingSecurityScopedResource before and after the writing operation.

  2. Otherwise ask the user for the locations on launch or just before the move operation.