NSSavePanel: Another sandbox issue

  • In my app I put up a save panel to save a file in a particular place within my ~/Library/Application Support folder. When not sandboxed, this works fine. When sandboxed, the URL that is set in the panel is correct (it's inside the sandbox now), but the save panel doesn't appear. In fact, it acts as if it's visible, but it's not, so my app enters a state that the user cannot recover it from - I have to stop it in the debugger or Force Quit.

    The stack trace is:

    #0    0x00007fff85ba667a in mach_msg_trap ()
    #1    0x00007fff85ba5d71 in mach_msg ()
    #2    0x00007fff897cb50c in __CFRunLoopServiceMachPort ()
    #3    0x00007fff897d3c74 in __CFRunLoopRun ()
    #4    0x00007fff897d3486 in CFRunLoopRunSpecific ()
    #5    0x00007fff897e319f in CFRunLoopRun ()
    #6    0x00007fff89e90bdc in -[NSRemoteSavePanel beginSheetModalForWindow:completionHandler:] ()
    #7    0x00000001000a7eae in -[GCOrteliusDocument(Templates) saveCopyAsTemplateAction:] at /Users/grahamcox/Projects/Artboard/Artboard/Source/Code/GCOrteliusDocument+Templates.m:310
    #8    0x00007fff8982e70d in -[NSObject performSelector:withObject:] ()
    #9    0x00007fff8af55f7e in -[NSApplication sendAction:to:from:] ()

    The code is very simple:

    NSSavePanel*  savePanel = [NSSavePanel savePanel];

    <define completion handler - omitted for brevity>

    [savePanel setCanCreateDirectories:YES];
    [savePanel setCanSelectHiddenExtension:NO];
    [savePanel setExtensionHidden:YES];
    [savePanel setDirectoryURL:[[self class] userTemplatesURL]];  // URL differs if sandboxed/not sandboxed

    [savePanel beginSheetModalForWindow:[self windowForSheet] completionHandler:completionHandler];

    Anyone else come across this issue? My understanding is that with sandboxing, the save panel is a bit more involved since it has to open up holes in the sandbox on behalf of the user, but in this case it's actually inside the sandbox.

    --Graham
  • > [savePanel beginSheetModalForWindow:[self windowForSheet] completionHandler:completionHandler];
    >
    >
    > Anyone else come across this issue? My understanding is that with sandboxing, the save panel is a bit more involved since it has to open up holes in the sandbox on behalf of the user, but in this case it's actually inside the sandbox.

    More info - I just noticed that this is getting logged.

    31/05/12 9:54:01.793 AM com.apple.security.pboxd: *** -[__NSArrayM insertObject:atIndex:]: object cannot be nil
    31/05/12 9:54:01.793 AM com.apple.security.pboxd: 2012-05-31 09:54:01.792 com.apple.security.pboxd[15928:1707] *** -[__NSArrayM insertObject:atIndex:]: object cannot be nil
    31/05/12 9:54:01.794 AM com.apple.security.pboxd: (
    0  CoreFoundation                      0x00007fff8983ef56 __exceptionPreprocess + 198
    1  libobjc.A.dylib                    0x00007fff89d41d5e objc_exception_throw + 43
    2  CoreFoundation                      0x00007fff897e5ab8 -[__NSArrayM insertObject:atIndex:] + 296
    3  com.apple.security.pboxd            0x000000010f0eadb6 com.apple.security.pboxd + 19894
    4  FinderKit                          0x00007fff8e2eb4e3 -[FIFinderViewGutsController browserSelectionChanged] + 93
    5  FinderKit                          0x00007fff8e263af2 -[FI_TBrowserViewController selectionChangedByUserAction:] + 130
    6  FinderKit                          0x00007fff8e2b4a86 -[FI_TColumnViewController selectionChangedByUserAction:] + 91
    7  FinderKit                          0x00007fff8e2b8ac7 _ZN17StColumnOptimizerD2Ev + 153
    8  FinderKit                          0x00007fff8e2b0a0d -[FI_TColumnViewController openTarget] + 1301
    9  FinderKit                          0x00007fff8e2efb82 -[FIFinderViewGutsController commonFinishInitialization] + 103
    10  FinderKit                          0x00007fff8e2ec387 -[FIFinderViewGutsController buildBrowserView:] + 167
    11  FinderKit                          0x00007fff8e2ec84f -[FIFinderViewGutsController setTargetPath:withViewStyle:] + 635
    12  FinderKit                          0x00007fff8e2ed21e -[FIFinderViewGutsController setViewStyle:] + 467
    13  Foundation                          0x00007fff8de9ac46 _NSSetObjectValueAndNotify + 261
    14  FinderKit                          0x00007fff8e2f2389 -[FIFinderView setViewStyle:] + 253
    15  AppKit                              0x00007fff8b389cd7 -[NSSavePanel beginWithCompletionHandler:] + 88
    16  com.apple.security.pboxd            0x000000010f0e985f com.apple.security.pboxd + 14431
    17  RemoteViewServices                  0x00007fff89e8d4d3 __45-[NSRemoteServiceConnection _setupConnection]_block_invoke_0141 + 69
    18  CoreFoundation                      0x00007fff897f3dfc __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    19  CoreFoundation                      0x00007fff897abf02 __CFRunLoopDoBlocks + 322
    20  CoreFoundation                      0x00007fff897d3fa7 __CFRunLoopRun + 2023
    21  CoreFoundation                      0x00007fff897d3486 CFRunLoopRunSpecific + 230
    22  HIToolbox                          0x00007fff8a0964d3 RunCurrentEventLoopInMode + 277
    23  HIToolbox                          0x00007fff8a09d781 ReceiveNextEventCommon + 355
    24  HIToolbox                          0x00007fff8a09d60e BlockUntilNextEventMatchingListInMode + 62
    25  AppKit                              0x00007fff8ae52e31 _DPSNextEvent + 659
    26  AppKit                              0x00007fff8ae52735 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 135
    27  AppKit                              0x00007fff8ae4f071 -[NSApplication run] + 470
    28  com.apple.security.pboxd            0x000000010f0e8a35 com.apple.security.pboxd + 10805
    29  com.apple.security.pboxd            0x000000010f0e73e4 com.apple.security.pboxd + 5092
    )

    So, internally the panel is throwing an exception, due to a nil object. But why? what am I doing wrong here?

    --Graham
  • On 31/05/2012, at 9:57 AM, Graham Cox wrote:

    > So, internally the panel is throwing an exception, due to a nil object. But why? what am I doing wrong here?

    OK, some more discoveries.

    1. The problem only occurs with a delegate set on the panel. The delegate isn't called - just its presence is enough.
    2. The problem pertains only to column view. If I temporarily remove the delegate so the panel comes up, switch to list view, and put the delegate back, it's OK.
    3. When I use -setDirectoryURL: and the URL is somewhere in my sandbox, the actual URL displayed is the old location, back in ~/Library/Application Support (!)
    4. The save panel under sandboxing is currently a disaster, and this is a showstopper for adding sandboxing at this point. There is simply NO WAY Apple should be forcing sandboxing on developers as of tomorrow with the system in such a broken state. It's going to make them look very cavalier and arrogant indeed, and will hurt the reputation of OS X. "It Just Works"? My a**e.

    G.
  • > 3. When I use -setDirectoryURL: and the URL is somewhere in my sandbox, the actual URL displayed is the old location, back in ~/Library/Application Support (!)

    When using a sandbox in Mac OS X 10.7 and later, the home directory is the
    app’s container directory.  That is

    ~ ==> /Users/<user>/Library/Containers/<app>/Data/

    Now the fact that the application is sandboxed and lives in a container
    is irrelevant to the user.  Try taking off your developer hat and
    putting on your dumb user hat.  A user will want to save somewhere,
    perhaps in his Documents directory.  In a sandboxed app that will be
    /Users/<user>/Library/Containers/<app>/Data/Documents/

    The user doesn't know or care what the actual path is.  Why are you
    trying to show it in a save dialog.

    Marc
  • On May 30, 2012, at 7:54 PM, Marco S Hyman <marc...> wrote:

    > In a sandboxed app that will be
    > /Users/<user>/Library/Containers/<app>/Data/Documents/

    What? No! The whole point of sandboxing and NSSavePanel is that Powerbox will poke holes into the user's *actual* Documents directory.

    Graham, the behavior seeing is a known bug that was reported a while ago. There's more info on the dev forums but I can't access that right now.

    --Kyle Sluder
  • On 31/05/2012, at 12:54 PM, Marco S Hyman wrote:

    > The user doesn't know or care what the actual path is.  Why are you
    > trying to show it in a save dialog.

    I don't, as such, but the save panel shows the full path and it's simply wrong.

    I have a specific location inside my Application Support folder where I save templates. By saving them there, they are automatically included in the Template Browser, which is another part of my app. Because App Support is now inside the sandbox, that's where it needs to go, and that's no problem. Except that when I try to set  this directory, the save panel takes me to the OLD ~/Library/Application Support/... directory. I could save the file there, except that it's outside the sandbox, and my template browser is not looking there any more.

    If the save panel hid the real location from me by hiding part of the path and making it look like ~/Library/App Support, that would be fine, but it doesn't do that - it literally sets the incorrect directory outside of my sandbox.

    One possible reason for it might be that there is a folder in the old location for my previous version's app support - I need to check if that is the cause of the confusion. But that's not going to help our users who are upgrading from the previous (non sandboxed) version and will have those directories.

    The right thing for Apple to do at this point is to revoke the sandboxing requirement until 10.8. (or possibly until whatever version of 10.7.x is verified to work properly and we can have sandboxing conditional by version) Who's going to step up to the plate and make the decision?

    --Graham

    P.S. Just saw this: http://www.macworld.com.au/news/ac-devs-air-frustrations-at-mac-app-store-s
    andboxing-debacle-55502/

  • I would say that's a pretty reasonable article about the current state of sandboxing as I understand it. I've given up for a while on the OSX thing I was writing (which uses iCloud so it has to be sandboxed) because struggling with the entitlements at the same time as struggling with OSX (I started from iOS and so OSX is still a little alien) was frustrating. I read the forums and follow quite a few threads to see how things are evolving, I'll go back to it one day.

    I'm sure Apple employees read the dev forums, I wish they replied a bit more, I think they could both help a lot of people who are thrashing around in the dark and get more rapidly to finding all the edge cases in the sandbox and help people to file better bug reports. It's rather hard to file good ones when you really don't have a clue how it's supposed to work in the first place. I think they could make the process of making sandbox better, or fit for purpose, a bit more collaborative and it would help everyone, themselves included.
  • On May 30, 2012, at 10:54 PM, Marco S Hyman wrote:

    >> 3. When I use -setDirectoryURL: and the URL is somewhere in my sandbox, the actual URL displayed is the old location, back in ~/Library/Application Support (!)
    >
    > When using a sandbox in Mac OS X 10.7 and later, the home directory is the
    > app’s container directory.  That is
    >
    > ~ ==> /Users/<user>/Library/Containers/<app>/Data/
    >
    > Now the fact that the application is sandboxed and lives in a container
    > is irrelevant to the user.  Try taking off your developer hat and
    > putting on your dumb user hat.  A user will want to save somewhere,
    > perhaps in his Documents directory.  In a sandboxed app that will be
    > /Users/<user>/Library/Containers/<app>/Data/Documents/

    So, before I start waving my hands in the air, running around the office and panicking, does this mean that the user can not save files where ever he/she wants to on the HD in future versions of the Mac OS?

    > The user doesn't know or care what the actual path is.  Why are you
    > trying to show it in a save dialog.
    >
    > Marc

    Sometimes, the user does.

    If sandboxing ALLOWS the user to save in a private special place but PREVENTS them saving files where they choose, then this is a scary path.

    I certainly hope this is not the case.

    In all of Apple's success, I see the openness and fun to use nature of the Mac platform running away right in front of us.
  • On May 31, 2012, at 2:43 PM, Alex Zavatone wrote:

    >
    > So, before I start waving my hands in the air, running around the office and panicking, does this mean that the user can not save files where ever he/she wants to on the HD in future versions of the Mac OS?

    No, it's completely and totally incorrect. It's obvious Marco either didn't read or didn't understand the Sandboxing Guide.

    --Kyle Sluder
  • On May 31, 2012, at 5:46 PM, Kyle Sluder wrote:

    >
    > On May 31, 2012, at 2:43 PM, Alex Zavatone wrote:
    >
    >>
    >> So, before I start waving my hands in the air, running around the office and panicking, does this mean that the user can not save files where ever he/she wants to on the HD in future versions of the Mac OS?
    >
    > No, it's completely and totally incorrect. It's obvious Marco either didn't read or didn't understand the Sandboxing Guide.

    OK, I'll watch the WWDC video on it and try to summarize to hopefully ward off some FUD.

    Thanks
  • On May 31, 2012, at 2:46 PM, Kyle Sluder wrote:

    > On May 31, 2012, at 2:43 PM, Alex Zavatone wrote:
    >
    >>
    >> So, before I start waving my hands in the air, running around the office and panicking, does this mean that the user can not save files where ever he/she wants to on the HD in future versions of the Mac OS?
    >
    > No, it's completely and totally incorrect. It's obvious Marco either didn't read or didn't understand the Sandboxing Guide.

    Read... but forgot.  And Kyle is also correct that I don't fully
    understand the Sandboxing Guide.  It doesn't help that every time I
    read it there is a new version.

    The problem I was replying to was an attempt to save something
    *inside* the sandbox container and had nothing to do with the Documents
    folder.  I mis-thought and mis-wrote as a result.  I'll shut up now.

    Marc
  • On May 31, 2012, at 5:46 PM, Kyle Sluder wrote:

    >
    > On May 31, 2012, at 2:43 PM, Alex Zavatone wrote:
    >
    >>
    >> So, before I start waving my hands in the air, running around the office and panicking, does this mean that the user can not save files where ever he/she wants to on the HD in future versions of the Mac OS?
    >
    > No, it's completely and totally incorrect. It's obvious Marco either didn't read or didn't understand the Sandboxing Guide.
    >
    > --Kyle Sluder

    OK Kyle, I've watched the WWDC 2011 Session 203 - "Introducing the App Sandbox" video and read:

    http://developer.apple.com/library/ios/#DOCUMENTATION/Miscellaneous/Referen
    ce/EntitlementKeyReference/EnablingAppSandbox/EnablingAppSandbox.html


    Table 3-2 in the above link states that your app can be configured to save to files and folders the user opens.

    It also states that programmatic access (Table 3-3) can be enabled for Downloads, Music, Movies and Pictures. (Why not Documents?)

    So, it looks like you can set up an app to save into known places and also to let the user select where he/she opens/saves files in the file system. (Table 3-2 again).

    Now, I've got no experience with this.  I'm just trying to interpret the docs, so as I typed, it looks like this will be possible and not be a VIsta style permissions nightmare.

    I'm assuming you can still save app prefs in the ~/Library/Preferences/ folder, but your app can't save elsewhere, like to root, without a user directed action.

    From 31:36 in the WWDV Session 203 video:

    HOME = ~/Library/Containers/App/
    CFFIXED_USER_HOME = ~/Library/Containers/App/

    NSHomeDirectory() will return HOME (as defined above) and if you try to open("/Users/krsric/Library/foo") an action like this will be denied.

    I'm assuming that from the user's experience, the implications will (hopefully) be minimal.

    I wonder what would happen if the user quits the sandbox deamon, or if we, as users, will still have access to apps like Application Monitor, or have shell access in sandboxed applications.

    Admittedly, I don't have close to a grip around all of the potential implications sandboxing imposes, and what it may not affect.

    I do really recommend checking out the Entitlements reference and watching the video from 31:36 on.  Log in to developer.apple.com and get that video.

    Cheers,
    - Alex
previous month may 2012 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today