32

I'm developing an app that is currently sandboxed. It acts as a basic text editor. Recently, I wanted to test what happens when I open a file in my app and another app at the same time, make an update in one app, then then see the updated in the other. I'm using Coda or BBEdit as my alternative editors. If I turn off sandboxing -- then this issue does not exist. However, since apps are required to be sandboxed as of March 1, I would rather implement a solution rather than wait and see.

When I open both files and make an edit in my app and then switch to the other app, the changes are reflected so that those editors have the version just saved from my app. However, if I perform the converse of saving from their app and then moving to mine -- no joy. Without performing any action, the console reports two specific errors: deny file-issue-extension and deny file-write-data. The app appears to be losing privileges to edit the document since it was changed by an external editor after the document was opened in my app. If I try to save the file in my app, it asks to duplicate the document because it has lost access to the original document. This doesn't happen the other way around because those apps have not been sandboxed and therefor have permissions that my app does not. It also doesn't appear that you can prevent the other app from making the changes if you don't want this behavior.

The documentation on developer.apple.com mentions nothing of this type of situation. I am not sure if this is intended behavior. If it is, then I can just tell my user that the document permissions have been lost and they should either save a new version or re-open the file. If it is NOT intended behavior, then what method in the NSDocument API would grant permission to the file once it has been lost? I'm assuming the answer is the former, that this is intended, but can anyone confirm and is there documentation?

Scott Harwell
  • 7,457
  • 2
  • 28
  • 41
  • I ended up coding around this issue. If the app loses permission to the file, then I tell the user to save my doc as a new file or close. But, it doesn't seem like one app should be able to "steal" permissions from another. I guess this is the price you pay for a sandbox. – Scott Harwell Jan 13 '12 at 14:20
  • I found Apple's default message that the document was edited outside of the app. Looks like this is intended. – Scott Harwell Jan 13 '12 at 15:58
  • 3
    Please file a radar (and maybe document it on [OpenRadar](http://openradar.appspot.com/)) - there are many problems with sandboxing in its current form, and the more bug reports Apple gets, the more likely they are to fix/postpone/retract sandboxing. – fzwo Jan 16 '12 at 17:53
  • 1
    Unfortunately, I don't think this is a bug for OpenRadar. I think it's an undocumented side effect of opening a document in a sandboxed application which has annoying, but not detrimental, effects on the end user. The user simply need to save the document as something else (or over the edits made by the other app). What this means as a developer is that your app will not be able to poll for changes from other apps and apply them directly. Rather, the poll would only allow you to tell you user to save as since it loses permissions to the file. – Scott Harwell Jan 16 '12 at 18:39
  • 2
    If you feel this makes for poor user experience or hinders development of certain features, I still feel you should file a radar with Apple. – fzwo Jan 16 '12 at 21:50
  • You and everyone else interested in this should file a radar nevertheless, Apple says it's the only way to get eyeballs on the issue and i am sure you want that. – valexa Feb 29 '12 at 15:33
  • 5
    I suspect this is linked to the other apps saving atomically. This, in turn, changes the file inode (it's another file). The new file is not in your sandbox anymore. You can check whether inode changes by invoking `ls -i` in Terminal before & after saving the file. – rsebbe Apr 24 '12 at 19:53
  • @rsebbe Yes, that is exactly what is happening. I have a check in place now. At the time, I was hoping for a way around it. – Scott Harwell Apr 24 '12 at 20:08
  • 1
    I haven't actually done this yet, but the Sandbox doc indicate that NSDocument coordinates this using NSFileCoordinator and NSFilePresenter. It looks like there is support in NSFilePresenter for being notified that there is a new URL, which might have the right privileges. – gaige May 27 '12 at 11:54

2 Answers2

1

Without performing any action, the console reports two specific errors: deny file-issue-extension and deny file-write-data. The app appears to be losing privileges to edit the document since it was changed by an external editor after the document was opened in my app. If I try to save the file in my app, it asks to duplicate the document because it has lost access to the original document

The correct behavior in a situation like this is to not overwrite the file, but to prompt the user if they want to reload the document, if so reload it and then write it.

The OS is doing the right thing by not allowing a blind write over a file that has changed.

See NSFilePresenter - (void)presentedItemDidChange to see if it changed. Reread the file and then see if you can save it. You dont say you have been denied a read on the file.

Also, since you havent posted any code it might be helpful to show what code you are using to access the file and to save it. NSDocument has built in handling for some types of file changes in the sandbox.

deleted_user
  • 3,817
  • 1
  • 18
  • 27
  • This question is more of a general question that related to specific code regarding my app's interaction with the document. Any code provided would not accurately give context to the overall issue that this happens. I'm not sure I agree with "The correct behavior in a situation like this is to not overwrite the file, but to prompt the user if they want to reload the document, if so reload it and then write it." In fact, there are times where I use non-sandboxed text editors (as in this question) to do just that. However, with the sandbox as a context, then I do agree with your first sentence. – Scott Harwell Aug 08 '12 at 13:34
  • Your suggestion to reload the document is probably the only true solution in a sandboxed environment. I do not think that it will always be the best solution for app users, but the sandboxed versus not sandboxed argument is not something I intended to get into with this question. I'll mark this as the answer. Thanks for your suggestions! – Scott Harwell Aug 08 '12 at 13:37
0

Lets call your App ScottEdit and your competitor as StackEdit

There could be several things going on. NSDocument has a lockDocument method. StackEdit may have locked the document and did NOT unlock it after save. If you quit the app, the file should be unlocked and available for your app. If this is the case, you will need to create a notification for when the file attributes change using kqueue or another.

If the other app is "blocking" access to your app. You can send an email to that developer and ask him to update his app so it unlocks the document after save. This last step is in addition to setting up notifications because another developer may come along and do the same thing (breaking your app).

Cocoa Dev
  • 9,361
  • 31
  • 109
  • 177
  • 1
    "You can send an email to that developer and ask him to update his app so it unlocks the document after save." isn't a viable solution. Assume working with text files and all the text editors out there -- that's a lot of emails. This isn't a lockDocument issue or a broken app issue. It's a sandbox permissions issue. The sandbox will not allow the application to edit the file once it has been modified externally. – Scott Harwell Aug 03 '12 at 14:41