I need to accomplish following three things. I am not sure how to go about it using Swift and Xcode
Package an existing CLI tool with the APP.
Use swift to issue commands to this CLI app and let it do its thing.
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.
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:
Your app must be signed.
The helper tool must be signed.
The helper tool must be located in the Contents/Library/LaunchServices directory inside your app's bundle.
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".
The helper tool must have an embedded launchd property list.
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.
The helper tool must have an embedded info property list.
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.
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.
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.
Related
I have googled and searched here and have come up empty.
I have an application that installs a system extension and I'm resorting to writing to a file when the extension is installed to know.
Is there an objective C or Swift function that does essentially what systemextensionctl list does? This is a sandboxed app and I don't want to (and suspect I can't) fork/run a shell command.
There is still no public API to do that, but there is a way to use the private API under the systemextensionctl, OSSystemExtensionClient, as described here.
You will need to reverse the OSSystemExtensionClient futher to get the list of extensions.
It also may be that you can find desired information in some .db files.
Both things are not considered as public and could be changed at any moment.
I'm successfully using the great Swift wrapper for sqlite from https://github.com/stephencelis/SQLite.swift in a Cocoa application.
But when I try to use the wrapper in a Command Line Tool project and follow the same detailed installation steps I get the following error:
Check dependencies
Unable to run command 'PBXCp SQLite.framework' - this target might
include its own product.
I checked the dependencies, but couldn't figure out how to solve this.
You can't link dynamic framework (a .framework) with your app in a Command Line Tool project. The reason is simple — a command line tool target builds a single binary file. This is unlike a regular Cocoa application, where the .app "file" is actually a folder containing .frameworks and other stuff inside.
So basically you'd have to build a static library instead (one that links with your app's binary during compilation) — except that as of Xcode 6.1 it's not possible yet with Swift.
So the only thing you can do — AFAIK — is add the SQLite.swift's source code directly into your own app target (so it compiles together). It's ugly, but works.
I have a C program that I build using Makefiles on OS X and I'd like to add the version/build number so that it is included in any crash reports. How can this be done without putting the binary as part of an app bundle?
As you may have realised, the standard OSX method is to create a bundle and add the version in the Info.plist and there isn't the usual attributes available within the binary executable, as you'd find in Windows.
Many terminal apps will allow you to discover their version with a -v option, but this is usuallly just a function returning the version number.
If you want to add meta data without hard coding it, you could use the extended file attributes to store the version number, which you can read, write and view with the xattr command.
On Mac OS X, binary executables in the DYLD format contain "loader commands" that instruct the library loading system how to handle the contents of the file. In particular, the loader command instruct the system where dependent libraries should be searched for, etc.
You can see the complete list of loader commands for any binary on your system by running "otool -l /path/to/your/app".
Generally speaking these loader commands are set by the "ld" tool during the link phase of a project's compilation.
My question is, what do I need to do to add loader commands for publicized types that are not supported (apparently) by ld?
In particular, I would like to take advantage of the LC_DYLD_ENVIRONMENT loader commmand, which can be used to specify a string in the loader commands table of a binary that should be loaded and evaluated as environment variable settings in the context of the executable.
I don't see any argument to ld that would facilitate this. Something like "-sectcreate" but for specifically adding to the content of the loader commands, is what I'm after.
I know this is possible because at least one standard app on Mac OS X uses it: Safari. But I don't know whether they achieve this by some kind of post-link massage of the binary, if they're using a custom version of ld that knows how to build and chain the custom loader command in, or if they are exploiting a general-purpopse feature of the ld command that I haven't been able to figure out.
It looks like you can use -dyld_env, like so: "-dyld_env DYLD_FRAMEWORK_PATH=/". This isn't documented in the man page, but can be found in ld64's Options.cpp and mentioned in the Changelog file. If you're trying to do it from Xcode, you'll probably have to do it like this: "-Xlinker -dyld_env -Xlinker DYLD_FRAMEWORK_PATH=/".
One thing to note: if you look at dyld's dyld.cpp, you'll see that it only allows environment variables that start with DYLD_ and ends with _PATH.
If your executable is structured as part of a standard OS X application bundle (i.e. a .app that can be launched by a user), the conventional way to specify application specific environment variables is through its plist file using the LSEnvironment key. See here for more information.
I am implementing one mac application.Its window version is already implemented.Now i am facing the following issue:
Implementation of new package with multi language (user could choose the language of the application while installing the app). ie For the windows version of the software, when executing the installation file user could choose the language in which the application should be installed. I want this feature to included in the mac version. ie the while installing the app using the package created the user should be able to choose the language of installation.(Currently in the mac version multilanguage is implemented using NSLocalizedString so that the app displays language according to the machine language and the installation package is localized). But i specifically want the users to be able to choose the installation language of the app, while installing.Pls help to solve this issue….
Use NSString *locString = NSLocalizedStringFromTable(#"key", #"Japanese", #"comment for key"); instead ;)
Explanation:
If you look at NSLocalizedString macro definition you will find that it actually calls -[NSBundle localizedStringForKey:value:table:] method in which the last parameter is the localization file (ie: Localizable.strings). You can get available localizations with-[NSBundle localizations]; method.
This means that you could use it to directly access a localization file like this:
// This gets the localized string found in Japanese.strings for the key #"key"
NSString *locString = [thisBundle localizedStringForKey:#"key"
value:#"No translation"
table:#"Japanese"];
Or use the macro (Which is almost equivalent)
NSString *locString = NSLocalizedStringFromTable(#"key", #"Japanese", #"comment for key");
The difference is what happens when the given key is not available:
the former returns #"No translation"
the latter returns the default localization for #"key"
Please see NSBundle class reference for more details
Hope it helps