0

I have a sandboxed Cocoa app that allows the user to open and manipulate directories.

I'd like to disallow deleting special system folders such as the user's Documents and Desktop folders.

How can I tell if a file URL points to a special, protected system folder as defined in FileManager.SearchPathDirectory?

I use NSOpenPanel to open a folder. For the desktop folder, I get:

/Users/bob/Desktop

Now, FileManager has the handy method url(for:in:appropriateFor:create:) for locating special directories. For example:

FileManager.default.url(for: .desktopDirectory, 
                        in : .userDomainMask, appropriateFor: nil, create: false)

returns:

/Users/bob/Library/Containers/com.mycompany.app/Data/Desktop

... which is expected, as this is a sandboxed app. But the problem now is that comparing these two urls fails, although semantically, they represent the same folder. How can I tell that they indeed point to the same folder?

Mark
  • 6,647
  • 1
  • 45
  • 88

1 Answers1

0

The difference between the sandbox URL to a user-relative special folder and the non-sandbox one is always Library/Containers/<bundle id>/Data.

For your purposes both the sandbox and non-sandbox paths should presumably both be protected from deletion, indeed anything in ~/Library/Containers maybe should be protected.

So if FileManager.default.url returns a URL with a path of the form /Users/<name>/Library/Container/<bundle id>/Data/<folder...> you can use NSRegularExpression to match against this and map it to /User/<name>/<folder...>. Writing the RE is left as an exercise!

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86
  • Thanks for your suggestion, but the problem is the other way around: I receive the URL `/Users/bob/Desktop` from the Powerbox via NSOpenPanel and have to decide if *this* is a protected system location. I know that all results to `FileManager.default.url(for:in:appropriateFor:create:)` are protected system locations (by design). My problem is that I can't match those against the user-provided location. – Mark Dec 19 '19 at 08:08
  • Maybe I'm misunderstanding something here about your problem but surely it doesn't matter which URL you get from which source as you can map them to each other in either direction by inserting or removing `Library/Containers//Data/`. – CRD Dec 19 '19 at 08:50
  • My concern is that the pattern `Library/Containers//Data/` is an implementation detail. The location could change, breaking the mapping. My question is, if there is an official API to tell if a user-provided path is the Desktop folder, for example. – Mark Dec 19 '19 at 13:32
  • OK, read this [Q&A](https://stackoverflow.com/questions/9553390/how-do-i-get-the-users-home-directory-in-a-sandboxed-app/9553507#9553507) and you'll find out how to get a users real home directory - using `getpwuid()` - and the sandboxed app's effective home directory - using [`NSHomeDirectory()`](https://developer.apple.com/documentation/foundation/1413045-nshomedirectory?language=objc). The difference between these two is the string you are concerned may change, and if the real home is not a prefix of the sandbox home you know there has a major system change. Does that help? – CRD Dec 19 '19 at 15:57