0
votes

I'm trying to read the contents of a file on the filesystem in a macOS Swift app (Xcode 9 / Swift 4).

I'm using the following snippet for it:

let path = "/my/path/string.txt"
let s = try! String(contentsOfFile: path)
print(s)

My problem is the following:

  1. This works in a Playground
  2. This works when I use the Command Line Tool macOS app template
  3. This terminates in a permission error when I use the Cocoa App macOS app template

The permission error is the following:

Fatal error: 'try!' expression unexpectedly raised an error:

Error Domain=NSCocoaErrorDomain Code=257 "The file "data.txt" couldn't be opened because you don't have permission to view it."

UserInfo={NSFilePath=/my/path/data.txt, NSUnderlyingError=0x60c0000449b0 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}

I guess it's related to sandboxing but I found no information about it.

  1. How can I read from the filesystem in a sandboxed app? I mean there are so many GUI apps which need an Open File dialog, it cannot be a realistic restriction of sandboxed apps to not read files from outside the sandbox.

  2. Alternatively, how can I switch off sandboxing in Build Settings?

  3. Finally, I tried to compare the project.pbxproj files between the default Cocoa Apps and Command Line Tool template and I didn't see any meaningful difference, like something about security or sandbox. If not here, where are those settings stored?

1
You are sandboxing your app without knowing why you need to do it. Otherwise, you wouldn't have a line like let path = "/my/path/string.txt".El Tomato
I do not want to sandbox my app, I just want to read a file from the file system in a Cocoa App template based app.hyperknot
If you do not want to sandbox your app, then why do you ask "How can I read from the filesystem in a sandboxed app?"?El Tomato
I don't want sandbox, but would still like to understand how a sandboxed app should solve this problem.hyperknot

1 Answers

1
votes

Your bullet 1: you have the answer, you need to use NSOpenPanel to obtain the user's permission to access the file. You can use NSOpenPanel methods to restrict the user's choice to the cancel button and just the file you wish - thus making a "request access to" dialog. Start with Apple's App Sandbox Design Guide.

Your bullet 2: you've the right idea, just the wrong tab, you should find the sandboxing switch on the Summary tab.

HTH