Packaging Unity Games for the Mac App Store

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)
  • Unity
  • Some technical savvy (this isn’t a complete handholding, just notable stuff)

Certificates

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):

Application Changes

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:

Icon

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).

Info.plist

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:

"CFBundleIconFile", "icon.icns"

Replaces the Unity version with our own, looks like: “Blush version 1.0.10.5123″.  The last version number is actually our current Asset Server revision number:

"CFBundleGetInfoString","$game version $versionExpanded"

Replaces the Unity number with ours:

"CFBundleShortVersionString", "$version"

Same replacement, different variable:

"CFBundleVersion", $version

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:

"CFBundleIdentifier", $identifier

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:

"CFBundleName", $shortIdentifier

New key.  Apple provides a list of genres–this plist entry must match the primary category type you set when uploading your application:

"LSApplicationCategoryType", "public.app-category.arcade-games"

Apple requires this key, which isn’t present by default in Unity builds.  Ours looks something like: “Blush v1.0.10.5123 (c) Flashbang Studios, LLC”:

"NSHumanReadableCopyright", "$game v$versionExpanded $copy"

Fixing Permissions

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"

Certificate Signing

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.

Compliance

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!

Good Luck!

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!

This entry was posted in Tutorials. Bookmark the permalink.

5 Responses to Packaging Unity Games for the Mac App Store

  1. laurent says:

    Thanks for this, I did not even think about releasing my game on the mac app store but you make it sound so easy I will actually do that.

  2. Simon Edis says:

    Thanks for sharing this info Matt – you saved me days of frustration! Hope I can repay the favour one day. Cheers!

  3. Oded Sharon says:

    Apparantly you need a new build of Unity if you’re using 3.1

  4. John Grden says:

    One nice tidbit of info on testing your package is that you can run this command line. It will verify that your app will install correctly when downloaded from the appStore:

    sudo installer -store -pkg path-to-package -target /

  5. John Grden says:

    Just a few notes on my experience:
    1. Spaces DID make a difference in the Bundle Name – as far as I could tell, it should match the “appName” of your Bundle ID (ie: com.rockonflash.com.ShellShockHD = Bundle Name would be “ShellShockHD”
    2. I used Unity3D 3.2f4 to make the build. I still had to use the img2Icns tool to create my icons. I received an error about a 512×512 icon not being included. I had realized that I had overridden the icon selection in the IDE, but I would have assumed it would still generate the proper icons. When I viewed in Previewer, the Unity generated version had fewer icons than the one generated by img2icns.
    3. This was odd to me, but Bundle Version String, short came back with an error from iTunes that it needed to be 3 numeric characters separated by a period (ie: 1.0.0). It originally had a full string about unity version in there, but changing it to 1.0.0 fixed it. So it wants just the versioning of your app.

    Everything else went fine and it’s uploading as I type this ;) Thanks for the help!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>