The Mac App Store is slated to launch on January 6th, with Apple already accepting submissions for applications. The signing process for Xcode projects is fairly similar to their iPhone workflow. But how do sign an external application, one you don’t have source code for? Let’s take a look:
Things You Will Need
- The latest version of Xcode
- A Mac Dev Center account ($99/year)
- Some technical savvy (this isn’t a complete handholding, just notable stuff)
To submit an application to the Mac App Store, you need two signatures. A web wizard will walk you through creating these certificates when you first access the Developer Certificate Utility:
Note that if you intend to submit applications from multiple computers, you should export the private key for each certificate. Select the certificates and export from Keychain (it will prompt for a password to protect the resulting .p12 file):
First, build from Unity. You must select Intel-only as your architecture; this is a requirement of the App store. Once you have your .app bundle, you need to make a few changes:
Make sure you use a custom icon for your application. Unity should be able to do this for you now. We set up custom icons in our build pipeline before Unity added support (via the makeicns utility, which turns a 512×512 PNG into a proper .icns file for us).
Every Mac application contains an Info.plist with things like version information, copyright text, etc. The Mac App Store requires a few changes and additions to the Info.plist after Unity builds your app. You can edit these by hand (right-click your application, show contents, find Contents/Info.plist, double-click to edit with Property List Editor, or simply edit manually in any old text editor).
We use a PostprocessBuildPlayer script, written in PHP, that modifies our Info.plist here. Here’s what we’re doing (and why)–note that the variables here are actual variables from our PHP script:
Our own icon file. You probably won’t need to change this:
Replaces the Unity version with our own, looks like: “Blush version 184.108.40.20623″. The last version number is actually our current Asset Server revision number:
"CFBundleGetInfoString","$game version $versionExpanded"
Replaces the Unity number with ours:
Same replacement, different variable:
Apples requires you set the bundle identifier to match the app ID you set in the Mac Dev Center. In our case, this is something like com.flashbangstudios.blush:
This is just the tail end of our identifier–ie just “blush”. You may encounter an error when uploading your app if the name includes spaces:
New key. Apple provides a list of genres–this plist entry must match the primary category type you set when uploading your application:
Apple requires this key, which isn’t present by default in Unity builds. Ours looks something like: “Blush v220.127.116.1123 (c) Flashbang Studios, LLC”:
"NSHumanReadableCopyright", "$game v$versionExpanded $copy"
Unity builds have improper permissions set on the Contents/Data folder in the app bundle. The installer packaging only looks at the everyone/other permission flag, which isn’t set. This means the folder will be unreadable after packaging and subsequent installation, which causes a crash.
You can fix this manually by changing the Contents/Data folder to readable by everyone, or use a command line fix:
chmod -R a+xr "/path/to/Your Game.app"
Once you have modified your application, you’ll need to sign the .app bundle with the application certificate from the Mac Dev Center. These tools are available in the “Application Utilities” download.
The command to sign an application looks like:
codesign -f -v -s "3rd Party Mac Developer Application: Flashbang Studios, LLC" "/path/to/Your Game.app"
Once your application is signed, you must build an installer package. This looks like:
productbuild --component "/path/to/Your Game.app" "/Applications" --sign "3rd Party Mac Developer Installer: Flashbang Studios, LLC" "/path/to/output/game.pkg"
That’s it! You only upload the resulting .pkg file.
Apple has stringent technical requirements for applications in the Mac App Store. It appears that Unity is compliant, with the sole exception that it writes PlayerPrefs data into ~Library/Preferences/com.your.application.identifier. This is a sane location, so hopefully Apple won’t reject based on this alone.
Also, we aren’t checking installation receipts–verifying checking Apple’s DRM–which appears to require intervention from Unity themselves (your application must check receipts and shut down before showing any UI, and any plugins/code you could write would execute after Unity has already displayed something).
Update: Two fixes are required for Unity games build with 2.6.x, as mentioned on this thread:
For Unity 2.6.x users:
a) Jonas already posted updated Unity Player that addresses “thread_stack_pcs” problem. You can download it here: http://files.unity3d.com/jonas/UnityPlayer.zip
b) Also we prepared mono dynamic library update that addresses “~/.wapi” problem. You can download it here: http://files.unity3d.com/mantas/libmono.0.dylib.zip
NOTE: 2.6.x fixes are beta quality code and you need carefully test your game for regressions.
Short update instructions after you made your final app build with Unity Editor:
1) Extract UnityPlayer.zip. There will be UnityPlayer binary. Copy it over <YourFinalAppName>.app/Contents/MacOS/<binary found there>
2) Extract libmono.0.dylib.zip. There will be libmono.0.dylib binary. Copy it over <YourFinalAppName>.app/Contents/Frameworks/Mono.framework/libmono.0.dylib
There is a fixed build available for Unity 3.x, too, although it is currently in the beta cycle. Contact Unity if you need to get a hold of it!
Despite this article’s length, there really isn’t much to it: Edit some plist keys, sign your application, build the installer package, and upload to the Mac App Store. Best of luck to everyone submitting their games!