9 Replies
      Latest reply on Jul 19, 2019 10:46 AM by john daniel
      Macho Man Randy Savage Level 3 Level 3 (365 points)

        Setting NSSavePanel's directoryURL property to a directory inside a sandboxed app container does not work (actually sets the directoryURL to the "real" Documents directory.

         

        NSURL *containerDocsDir = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject;
        
        
        
        //...code here..
        //set the default save location for a savepanel..
        savePanel.directoryURL = containerDocsDir;

         

        This is a problem. If a Service takes a directory as input to set a default save location for a file that is to be saved  by NSSavepanel, it won't behave as expected.

        • Re: Setting NSSavePanel's directoryURL property to a directory inside a sandboxed app container does not work (actually sets the directoryURL to the "real" Documents directory.
          john daniel Level 3 Level 3 (390 points)

          The powerbox is designed to bridge the "real" world with the sandbox world. You don't want people navigating around inside your container. They will scramble your app for sure that way.

            • Re: Setting NSSavePanel's directoryURL property to a directory inside a sandboxed app container does not work (actually sets the directoryURL to the "real" Documents directory.
              Macho Man Randy Savage Level 3 Level 3 (365 points)

              Well, consider this:

               

              1) A sandboxed app provides a user interface that allows users to choose files inside the "Sandboxed container" documents directory.

              2) That same sandboxed app shows the Services menu. And now we have a Service that accepts a directory as a Send type.

              3) So the user fires the Service via the Services menu, then the Service provider gets the directory sent by the user as input and sets up a Save panel to use this directory as the default save location for some action.

               

              NSSavePanel doesn't honor the 'real path' of the directory, which seems wrong. In my testing, the Service provider and the app launching the Service are the same app. So in this case, I don't need a save panel to write to the directory, but another app may pass the sandboxed app  a location where a save panel is required. Having a separate code path to check if the directory is in a sandboxed container seems silly.

               

              In any case, this is the user's Mac. And if the user is savvy enough to navigate inside a sandboxed container's Documents directory and chooses to fire a Service from a Finder window (or another app) I feel like the directory path should be honored. But maybe I'm crazy.

                • Re: Setting NSSavePanel's directoryURL property to a directory inside a sandboxed app container does not work (actually sets the directoryURL to the "real" Documents directory.
                  john daniel Level 3 Level 3 (390 points)

                  The "Documents" folder inside the container is meant to be a private area for the app itself, not the user. You could use it à la iOS with a custom file browser, omitting the Finder altogether.

                   

                  Otherwise, you are living in really dangerous land. The Finder, powerbox, services, sandboxed app all cross the sandbox barrier multiple times. What you are asking is essentially the opposite of what most people have traditionally wanted from these bridging gateways.

                   

                  I don't really understand what you are doing, so I can't give specific tips. But, in general, I would say that your sandbox container is owned by the app and shouldn't never have the user, or especially some other app, digging around in it. If you need to exchange data (with either the user or other apps), use the user-level folders dedicated to that purpose. It sounds like the powerbox is trying to help you do that. Otherwise, your app is going to get scrambled.

                    • Re: Setting NSSavePanel's directoryURL property to a directory inside a sandboxed app container does not work (actually sets the directoryURL to the "real" Documents directory.
                      Macho Man Randy Savage Level 3 Level 3 (365 points)

                      >The "Documents" folder inside the container is meant to be a private area for the app itself, not the user. You could use it à la iOS with a custom file browser, omitting the Finder altogether.

                       

                      By that definition, the "Documents" folder in a sandboxed app virtually is no different than the Application Support directory. I think it's okay to use it that way In any case, sometimes apps want to allow users to drag and drop files to them, to move files into a directory that the app manages and/or use Services on their files that happen to be in this directory (the only directory a sandboxed app can write to without showing a permissions dialog). The purpose of the files in this directory inside my sandboxed container is defined by my app and the user.

                       

                      Anyway I didn't create this thread to argue about what my app is doing. You seem to be making excuses for what I consider to be a bug. I don't see why NSSavePanel would redirect the path of a sandboxed container's Documents folder to the "real" documents directory. This actually seems like a way a malicious developer could trick the user into accessing a directory that doesn't belong to him.

                       

                      1) Create a sandboxed app. Make a documents folder in code (so a Documents folder in the sandboxed container).

                      2) Have the sandboxed app create a folder named "Chicken" inside the documents directory of the sandboxed container.

                      3) Create a folder named "Chicken" in the real documents directory in Finder.

                      4) In the sandboxed app, show an NSSavePanel and set the directoryURL to the Chicken URL (of the sandboxed container).

                      5) See that the directoryURL in the save panel shown points to "Chicken" in the real Documents folder.

                       

                      This is what I noticed in debug mode. Maybe I had navigated to the "real directory" and state restoration brought it back on a previous launch; didn't have time to test it thoroughly.

                       

                      I'm no security nut, the user still has to hit "Save" in the save panel to write to "Chicken" but the behavior doesn't really make sense. Just have the  save panel point to the directoryURL that it was told. That's the fix.  I almost don't want to mention it because I fear Apple will take away the directoryURL property entirely or throw up a permissions dialog on top of the save panel, something like:

                      This app wants  to set the save location to your folder named "Ciicken". Confirm or Deny

                       

                      A dialog asking for permission on top of the save panel (which is a dialog asking for permission).

                       

                      Really, i'm just trying to use the same code path (to handle implementing a Service that can *write* anywhere the *user* wants me to write via NSSavePanel. My app also happens to use the Service it provides itself when fired on files in my own sandboxed container. And *I know* I don't need the save panel to write in this directory, but it just seems silly that I'm *not allowed* to use it.