How to access a packaged CLI tool using Swift on OSX

188 views Asked by At

I need to accomplish following three things. I am not sure how to go about it using Swift and Xcode

  1. Package an existing CLI tool with the APP.

  2. Use swift to issue commands to this CLI app and let it do its thing.

  3. Read the output stream coming from the CLI app in real-time if possible.

I have found NSTask that should be utilized, but I get App Previlege Issues and errors. SMJobBless sounds helpful but I am having hard time to understand all this. All I was trying to do was issuing some commands to a cli app that is already embedded within my app package.

1

There are 1 answers

0
Joshua Kaplan On

If you are looking to package a Command Line Tool you already wrote and have it run as root, that it is possible to do by installing it with SMJobBless but it's going to involve a bit of work. When installing a Command Line Tool in this manner, Apple refers to it as a helper tool. (Sometimes a privileged helper tool.)

For SMJobBless to succeed, Apple requires the following:

  1. Your app must be signed.
  2. The helper tool must be signed.
  3. The helper tool must be located in the Contents/Library/LaunchServices directory inside your app's bundle.
  4. The filename of the helper tool should be reverse-DNS format.
    • If your app has the bundle identifier "com.example.YourApp" then your helper tool may have a filename of "com.example.YourApp.helper".
  5. The helper tool must have an embedded launchd property list.
  6. The helper tool's embedded launchd property list must have an entry with Label as the key and the value must be the filename of the helper tool.
  7. The helper tool must have an embedded info property list.
  8. The helper tool's embedded info property list must have an entry with SMAuthorizedClients as its key and its value must be an array of strings. Each string must be a code signing requirement. Your app must satisify at least one of these requirements.
    • Only processes which meet one or more of these requirements may install or update the helper tool.
    • These requirements are only about which processes may install or update the helper tool. They impose no restrictions on which processes can communicate with the helper tool.
  9. The helper tool's embedded info property list must have an entry with CFBundleVersion as its key and its value must be a string matching the format described in CFBundleVersion's documentation.
    • This requirement is not documented by Apple, but is enforced.
    • While not documented by Apple, SMJobBless will not overwrite an existing installation of a helper tool with one that has an equal or lower value for its CFBundleVersion entry.
  10. Your app's Info.plist must have an entry with SMPrivilegedExecutables as its key and its value must be a dictionary. Each dictionary key must be a helper tool's filename; for example "com.example.YourApp.helper". Each dictionary value must be a string representation of a code signing requirement that the helper tool satisfies.

If you want to see a sample project that is configured to satisfy these requirements, you can take a look at SwiftAuthorizationSample.