Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Anyone use NSOpenPanel or other solution TOpenDialog in sandbox?


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 3 - Last Post: Nov 21, 2014 3:48 PM Last Post By: Grant Beattie Threads: [ Previous | Next ]
Grant Beattie

Posts: 77
Registered: 11/29/01
Anyone use NSOpenPanel or other solution TOpenDialog in sandbox?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 13, 2014 1:14 PM
As you may have seen me write before, a sandboxed desktop app (App Store configuration) can only access data in it's Library/Container, for example.

Users/username/Library/AppName/Data/Documents


but the standard open and save dialogs in FM utilize

Users/username/Documents


"and never the twain shall meet" ... or ... "you can't get there from here". My code needs to copy some files from my bundle into the/any user Docs area at startup, the first time it runs. And I need to alter the content of one or more of those files, all with no user intervention. This has not been an issue at all on Win32 or OSX in NORMAL configuration. Only when that damn container showed up did all hell break lose.

I can explain further the issue and why it exists, but I have no solution worked out yet? Anyone else faced this?

I figure one option is to make my own file picker form because it looks like Embarcadero has had the better part of two years to look at this. And hasn't. Or I can try and make TNSOpenPanel work but that looks frankly daunting.
Grant Beattie

Posts: 77
Registered: 11/29/01
Re: Anyone use NSOpenPanel or other solution TOpenDialog in sandbox?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 18, 2014 11:37 AM   in response to: Grant Beattie in response to: Grant Beattie
Its not possible to do this without user intervention.

I figure one option is to make my own file picker form

This cannot be done. It doesn't solve the restrictions situation in the sandbox.

Or I can try and make TNSOpenPanel work but that looks frankly daunting.

This looks like it will work. The user must be presented with an Open Dialog and they can then choose a destination for the sample files. Then you can bookmark the folder URL in order to get access to it in the future. Only NSOpenPanel will work. You certainly can't use TOpenDialog. I will try and work this technique out (in C++).
Grant Beattie

Posts: 77
Registered: 11/29/01
Re: Anyone use NSOpenPanel or other solution TOpenDialog in sandbox?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 20, 2014 11:22 AM   in response to: Grant Beattie in response to: Grant Beattie
Made some progress. From the sandbox I have figured out how to get access to the standard user's documents folder (or some other user-specified location). I can then create a directory in which to copy example files from my sandboxed bundle to this area. Some things required.

I added at the top of my C++ file:
   #include <MacAPI.ObjectiveC.hpp>
   #include <MacAPI.AppKit.hpp>
   #include <MacAPI.Foundation.hpp>
   #include <MacAPI.CocoaTypes.hpp>
   #include <MacAPI.Helpers.hpp>
   #include <FMX.Helpers.Mac.hpp>
   #include <FMX.Platform.Mac.hpp>


The following are missing from Macapi.Foundation.hpp, so I added these to my file (I think they are correct but will update if any errors found):
   static const System::Word NSURLBookmarkCreationWithSecurityScope = System::Word(0x800);
   static const System::Word NSURLBookmarkResolutionWithSecurityScope = System::Word(0x400);


In order to get direct access to NSOpenPanel I added at the top of my C++ file:
   namespace Apple
      {
      typedef _di_NSString            NSString;
      typedef _di_NSURL               NSURL;
      typedef _di_NSOpenPanel     NSOpenPanel;
      }
 
   Apple::NSOpenPanel openPanel;
   Apple::NSURL       openPanelUserPath;
 
   NSInteger openPanelResult;
   NSData   *myBookmark;
   NSError  *myError;
 
String  pathString;
TFileName myDocsPath;


On form creation I do:
   openPanel = TNSOpenPanel::Wrap( TNSOpenPanel::OCClass->openPanel( ) );
 
   openPanel->setAllowsMultipleSelection(false);
   openPanel->setCanChooseFiles(false);
   openPanel->setCanCreateDirectories(true);
   openPanel->setCanChooseDirectories(true);
   openPanel->setTitle(NSSTR(L"Select MyApplication Data Folder"));
   openPanel->setMessage(NSSTR(L"Choose or create a working folder for MyApplication data. Example: Documents."));
   openPanel->setPrompt(NSSTR(L"Select folder"));


At the start of my program I will prompt the user with this panel to select a folder that will be used to store the users created files
   openPanelResult = openPanel->runModal();
   if(openPanelResult == NSOKButton)
      {
      openPanelUserPath = TNSURL::Wrap(openPanel->URLs()->objectAtIndex(0));
      pathString = openPanelUserPath->relativePath()->UTF8String();
 
      myBookmark = openPanelUserPath->bookmarkDataWithOptions(NSURLBookmarkCreationWithSecurityScope, 0, 0, (void **)&myError);
 
      if(myBookmark)
         {
         myDocsPath = pathString + PathDelim + "MyApplication";
         if(System::Sysutils::DirectoryExists(myDocsPath) == false)
            CreateDir(myDocsPath);
         }


Finally on form destroy
   openPanel->release();


I can create the directory so I know that when a user selects a folder my bookmark is OK. Now I need to get access to that folder on subsequent program launches so that means I need to save this bookmark someplace and I need to use it later with startAccessingSecurityScopedResource, etc.
Grant Beattie

Posts: 77
Registered: 11/29/01
Re: Anyone use NSOpenPanel or other solution TOpenDialog in sandbox?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 20, 2014 3:59 PM   in response to: Grant Beattie in response to: Grant Beattie
Grant Beattie wrote:

   openPanelResult = openPanel->runModal();
   if(openPanelResult == NSOKButton)
      {
      openPanelUserPath = TNSURL::Wrap(openPanel->URLs()->objectAtIndex(0));
      pathString = openPanelUserPath->relativePath()->UTF8String();
 
      myBookmark = openPanelUserPath->bookmarkDataWithOptions(NSURLBookmarkCreationWithSecurityScope, 0, 0, (void **)&myError);
 
      if(myBookmark)
         {
         myDocsPath = pathString + PathDelim + "MyApplication";
         if(System::Sysutils::DirectoryExists(myDocsPath) == false)
            CreateDir(myDocsPath);
         }

Well I can't say for sure the bookmark is good. Only that it comes back non-zero. I can create the subdirs and files within the user selected area, but I think that's a property of the NSPanel at runtime only. I can't access anything using the bookmark such as myBookmark->length() or myBookmark->writeToFile(). So something is wrong... and it doesn't help that some of the Mac API is missing from the Embarcadero files.

Edited by: Grant Beattie on Nov 21, 2014 3:47 PM
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02