Sandboxed app: renaming files gives write error

Hi Guys,

I have an app that has been on the Mac App Store since before sandboxing was a requirement, named Quick File Renamer, which renames files in batch. They have allowed me to provide bugfix updates unsandboxed, but I would like to get it working in a sandboxed environment.

I have set entitlements to allow user selected files to have read/write permissions. However, even with read/write the user cannot rename files which were drag/dropped into the app or selected individually. If they do, they receive a read/write error.

If I select the entire folder, or select a new folder to copy the renamed files to, it works without error.

I have read in this article on StackOverflow that renaming a file actually requires write access into the parent folder: http://stackoverflow.com/questions/13950476/application-sandbox-renaming-a-file-doesnt-work

So my options are:

  1. Prompt the user to select the folder they want to place the renamed files in (doesn’t really work: in addition to being bad design the files might reside in many different directories)

  2. Find some way to get the sandbox to extend write access to the parent folder of the files

  3. Something else I haven’t thought of

Right now to rename the files I’m just doing a simple:

fBefore.Name = fAfter.Name

It’s hard to believe this is failing since the user selected the file specifically, but it’s true.

Any ideas?

Thanks!

-Mike

You do need access to the parent folder, you can’t rename a file in the same way that you can’t build a path to a file.

You can request the temporary entitlement giving your application access to the entire filesystem, consider the basic functionality of your application is to rename applications, the reviewer should grant you the TE, however be prepared if they don’t. In which case you may want to think about releasing outside of the Mac App Store.

An alternative is to ask the user where to save the re-named files (selectFolderDialog) and then use CopyFileTo, to change the name while copying the file. I realize that this will create duplicates, but you might be able to delete the original file?

I release outside of the app store as well but I still want to provide updates to the people who have already purchased in the app store. I didn’t realize I could get a TE for the entire filesystem, it sounded like I had to request specific directories. I will look into that more closely.

The expected behavior for me is what when the user selects the file, and my app has read/write access, I should be able to read the file, save over the file, delete the file, rename the file, copy the file. Doesn’t this inability to rename seem like a bug?

The app already does allow for CopyFileTo, which works sandboxed. However, it’s extremely slow to rename a bunch of movies that way.

The only way I can think of to overcome it is to wait for a write error, then pop up a SelectFolderDialog for that directory, and continue.

That is going to be a real pain for users who are taking files from a bunch of different directories and trying to rename them all at once. One example: I have photographers using this app on hundreds of wedding albums simultaneously, extracting EXIF dates from the metadata of the files and adding it as a suffix to the file name. Getting prompted for access to each of those folders is just wrong when they have specifically selected the files already.

Apps like Coda 2 utilize this TE, but from what I understand you need to have a pretty good reason to get approval for it.

Indeed you’re given read/write/delete/replace/copy ability for the file, but AFAIK renaming can only be done by the user in either the Finder or via the Titlebar (providing your application uses NSDocument).

I understand.

[quote=62578:@Mike Gibson]The only way I can think of to overcome it is to wait for a write error, then pop up a SelectFolderDialog for that directory, and continue. [/quote] This would get massively frustrating, and would irritate users beyond belief!

I suggest that you look into the TE, I feel you have a pretty good reason for needing it!

This would get massively frustrating, and would irritate users beyond belief![/quote]

This is what Unarchiver does. It’s a file uncompressor and they didn’t get the Temporary Entitlement, so you double-click on a file and the app can’t uncompress to the containing folder.

It’s ridiculously frustrating, but a possibility if the TE is not given.

I have an app that downloads subtitles and I have refrained from putting it into the MAS for precisely this reason. In sandboxes users can’t drop a movie or a folder and let the program save subtitles where the movies are. SO frustrating.

I agree! :slight_smile: It would only be really bad for users that are saving to multiple directories at a time. Most of the time it would only require the user to select one folder which would open up access to rename for every file in the folder, which I think is how most users approach renaming files. Still, a terrible solution.

I decided to go ahead and submit under the “bug fix releases are allowed to remain unsandboxed” rule and take it from there if it’s rejected. There’s always some new bug to fix when I want to release an update. :slight_smile:

Bullet dodged, for now. They approved it unsandboxed.

Congrats !

Well, I spoke too soon. For some reason they approved the full paid version, but not the free lite version, which they have rejected because it’s not sandboxed.

Any clue what the Temporary Entitlement for the whole filesystem is called?

In case anyone else comes here looking for the answer, I figured it out:

<key>com.apple.security.temporary-exception.files.absolute-path.read-write</key> <string>/</string>

Mike, congratulations. You should click the check on the upper right corner of your last message, so the thread will appear as answered. Good luck for the MAS.

Not so fast, they rejected it!

Reasons

2.31: Apps that are not sandboxed appropriately may be rejected

We’ve determined that one or more temporary entitlement exceptions requested for this app are not appropriate and will not be granted:

com.apple.security.temporary-exception.files.absolute-path.read-write: /

We understand this may prevent the app from being approved for the Mac App Store. We encourage you to investigate other ways of implementing the desired functionality.


Maybe I’m doing it wrong and I need a different entitlement?

The next move would be use Pictures, Music, Documents, etc entitlements and then when I get a write error make the user select the directory?

What a pain in the ass.

I submitted a support request since they’re going to expire in March anyway. Hopefully a tech can come up with a solution.

You got the right entitlement - but sounds like you got the wrong reviewer… This is the major draw back to temporary entitlements, the person reviewing your application! It appears unless they’re technically competent, they’ll just reject your application.

Try to talk to the reviewer first, if he won’t back down. Appeal the rejection on the grounds that your application simply cannot function without this entitlement (otherwise it no longer becomes a quick way of renaming files).

The funny thing is that they accepted the paid version, with exactly the same changes completely unsandboxed but rejected the free version sandboxed with the entitlement.

I guess it had different reviewers: one is a stickler for the rules, and the other is awesome and a great person to be friends with.

Apple Support replied with this:

Hello Mike,

[quote]I’m responding to your question about App Sandbox.

Yes, to rename a file you must have write permissions for the containing folder. This means that you may need to present an NSOpen/SavePanel both so the user can select the file itself and again to select the parent directory.

If you have the URL of that directory already, you can set the default location for the NSOpenPanel using its directoryURL property. That way the user won’t have to find that directory by hand.

Once the user gives your app access to the directory, you can create a security-scoped bookmark to it. Your app then can save that bookmark in its preferences. The next time the app runs, it can resolve that bookmark and get the same access to the directory as when the user chose it.

Best regards,[/quote]

I pretty much anticipated this and am putting systems in place to reduce the number of parent directory selections, as well as doing the Security Scoped Bookmarks, which are a pain.

[quote=65534:@Mike Gibson]Apple Support replied with this:
I pretty much anticipated this and am putting systems in place to reduce the number of parent directory selections, as well as doing the Security Scoped Bookmarks, which are a pain.[/quote]

Well, this is a bummer. I was waiting for a solution to this, as all my program does is save afiles next to the files inside dropped folders. I’d have to present dozens of Open/Save dialog boxes to the user.

I think you’ll be okay if they’re dropping folders. The user selected read/write entitlement will give you access to all of the files inside, and to the selected folder, when the user drops a folder on the app.

My renaming app works great when the user drops a whole folder of files or does a recursive search of a folder, it’s when they drop individual files that there are problems because I don’t get access to the parent folder.