Since the passage of moderation on the Mac Store began to require support for Sandbox, 5 years have passed. Although the capabilities of MacOS and Sandbox are gradually expanding, developers who want to publish in the official Apple store are still limited in their capabilities to work with this OS. This problem is especially acute for utilities and system applications.
Sandbox is designed to make macOS safer and protect the user from malicious and potentially dangerous applications - all applications that can hypothetically harm should be accompanied by a request to the user to provide access. In theory, this is a reasonable precaution, but in reality many applications that require user data to perform basic functions are subject to sanctions. In this article, we will describe how they implemented similar functions in the application, maintaining compatibility with Sandbox - perhaps this experience will be useful for other developers working with the official market.
We are faced with a similar need when working with the utility for monitoring the
MaCleaner X system. The entire MaCleaner product line is distributed exclusively through the Mac App Store.
')
Distinctive features of MaCleaner X are the
touchbar support and customized design: the application automatically detects the Mac model and offers a special interface option for each device. However, in addition to this, we are currently working on implementing in the extended version some functions that users would like to see in the program and which are considered familiar for utilities distributed outside the Mac Store.
First of all it is:
- removal of applications and all related information;
- Removal of unused service files from macOS (logs, localization, temp);
- obtaining system information about hardware (for example, about a hard disk);
- temperature monitoring and other system indicators.
Solution
To begin with, we will outline in general terms, according to which scheme the whole process will take place:
- The user must consent to access to extend the functionality (in fact, he will need to perform several actions outside the application);
- The application always works in the sandbox, but if necessary, before each action that requires administrative access rights, it requests permission from the user.
To perform this operation outside the sandbox, we will use the following macOS feature: applications that support extending their functionality using Apple Script can run these scripts outside the sandbox, if they are located in the ~ / Library / Application Scripts folder. An application that supports Sandbox cannot copy scripts to this folder by itself — this is stopped by Apple moderators.
Thus, the sequence of actions we have the following:
- Implementing a master application that supports extensions using Apple Script from the Application Scripts folder.
- Passage of moderation and publication of the application in the Mac Store
- Preparation of the extension-application. His tasks will include copying the necessary scripts into a shared folder with the master application. To do this, they must have a common AppGroup, through which the exchange will take place.
- Publication of the extension-application on its own website.
Example
As an example, consider the possibility of obtaining information about current media using the bash-command
system_profiler SPStorageDataType
.
Extension Application Preparation
All that is required of this component is copying the script to a specific folder. Therefore, in its interface we will display the only possibility: enabling or disabling the display of information about media (in order not to load the user with details, this can be represented as enabling / disabling plug-ins in the master application).
Apple Sript - bash
The contents of the file extract_storage_info.scpt, which is copied by ectention:
do shell script "system_profiler SPStorageDataType"
Preparing Master Applications
For the application to work correctly from the user's point of view, it is necessary to check the availability of additional functionality and hide the corresponding parts of the UI:
- (BOOL) isStorageInfoAvailable { return [self _storageInfoScriptTask] != nil; } #pragma mark - Private - (NSUserAppleScriptTask *)_storageInfoScriptTask { NSUserAppleScriptTask *result = nil; NSError *error; NSURL *directoryURL = [[NSFileManager defaultManager] URLForDirectory:NSApplicationScriptsDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&error]; if (directoryURL) { NSURL *scriptURL = [directoryURL URLByAppendingPathComponent: StorageInfoScriptFileName]; result = [[NSUserAppleScriptTask alloc] initWithURL:scriptURL error:&error]; if (error != nil) { NSLog(@"No AppleScript \"%@\" task error: %@", StorageInfoScriptFileName, error); } } else { // , Sandbox NSLog(@"No Application Scripts folder error: %@", error); } return result; }
If the script is available, it is called as follows:
NSUserAppleScriptTask * automationScriptTask = [self _storageInfoScriptTask]; if (automationScriptTask != nil) { [automationScriptTask executeWithAppleEvent:nil completionHandler:^(NSAppleEventDescriptor *resultEventDescriptor, NSError *error) { if (error != nil) { NSLog(@"AppleScript \"%@\" executing error: %@", StorageInfoScriptFileName, error);
In our simplified example, we display the string received from the executed script as is. To style an application, it will be necessary to parse the result and display only the necessary information.
Application collaboration
As a result, we get the following scheme of work.
Master application
- In case of unavailability of additional functionality, it hides UI elements.
- In the case of expanding scripts, Apple Script (in a specific format) activates the UI and executes them.
- If the functions that Apple Script performs require that the administrator's account data be entered, the user will see the standard authorization dialog — Apple Script will do the work for us.
Extension application
- Must be downloaded by the user from the developer site. We are talking about a special site, because it is necessary to explain to the user the principle of the system functioning and the actions that he needs to carry out in order to work correctly. In part, this can be done through the GUI extension.
- Despite the fact that we work outside the sandbox, we suggest using the general AppGroup for component solutions.
- This component can be represented even more widely - as an Extension Manager. Thanks to a consistent interface, the master application can expand as extensions appear in the shared folder: they can be added along with the description files and configurations.
- The Apple Script copied may even contain a common task function (bash_script) that accepts an arbitrary bash command as input and executes it. But this approach opens a big security hole, and also obliges the master-application to contain an extension before publishing to the App Store.
findings
Advantages of the approach:
- Expansion of application functionality
- Configurability extensions
Minuses:
- Not rational in terms of usability. An additional action is required from the user - downloading a third-party application.
- Potential security hole and the need for additional checks, format consistency.
This article offers a solution to the problem with product functionality restrictions dictated by Sandbox for developers. In the future, we will tell you about how the situation looks from the users. If you found other workarounds, we will be happy if you share them in the comments.