Access to macOS App Sandbox Entitlements


All the source code and project is available here on Github : MacOS_SandboxEntitlements



This is an example of setting up a macOS App that needs access outside the App Sandbox environment.  If you are going to submit a desktop macOS app to the Apple App Store it needs to run in the App Sandbox, but any user files need to be save outside the App Sandbox.  This requires some macOS API calls, and that what this example is all about.


The base of the project is C++/Qt but the sandbox entitlement access is done via Objective-C.   To make this work run the project with Xcode.  You'll need to do this because you need to setup the entitlements.


When the App Sandbox is enabled you need to create, save, and restore what is known as a Bookmark.  The Bookmark is created when you ask a user what they want to access.  In this example I ask a user for a directory to save a file in.  For Qt developers you can use QFileDialog to create the Bookmark.  For Objective-C developers you can use NSOpenPanel to get the Bookmark.  Both examples are included in this project.


In order for this to work in Xcode make sure to have App Sandbox enabled.  For the Target on the "Signing & Capabilities" page click the "+" in upper left corner to add the App Sandbox (double click label): 





And select the items you need.  Here I enabled File Access Type / User Selected File, I set it to Read/Write.  



This will create an entitlements file. EntitlementsExample.entitlements plist is  created for this project. 


The project uses a settings file stored in the App Sandbox folders.  The path is shown when app is executed.


If the user's path in the Settings file is blank, it allows a user to select the folder.  The Bookmark and Settings file are then updated.   Specifically the Bookmark is saved by calling


NSData *bookmark = 

[nsURL

      bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope

includingResourceValuesForKeys:nil

                 relativeToURL:nil

                         error:&error];


in the EntitlementBookmarks::SaveBookmarks() method.


When the app is executed the second time, the Settings will contain the users path and EntitlementBookmarks::RestoreBookmarks() is called to re-enable the bookmark.


NSURL* fileFolderURL = [NSURL 

 URLByResolvingBookmarkData:bookmark

                    options:NSURLBookmarkResolutionWithSecurityScope

              relativeToURL:nil

        bookmarkDataIsStale:&isStale

                      error:&error];



Also make sure to call


 BOOL success = [fileFolderURL

                 startAccessingSecurityScopedResource];



To start the entitlement access.



This is was designed to bookmark a folder so users can read and write files to that folder.  There are other options specially for accessing a single file, or a file for read-only.  See 


NSURLBookmarkCreationOptions


for more options.


No comments:

Post a Comment