Unity - Deploy on the Mac Store

  • 12/05/2016
  • Projects, Company, Blog

With the release of our game Lana & Tom I wanted to submit a standalone version of the game to the Mac Store. Let me show you how we did it! Head to the Unity Manual, we’ll be done in no ti...

1

With an outdated manual, it's not straightforward to deliver your game to the mac store today. Here I'll be trying to put together all the missing bits. May this article serve as a reminder that hitting the build button in Unity is often only the beginning.

Prerequisites

Application & Installer certificates
App is set up in the iTunes Connect Store
Application Loader

Step-By-Step Guide

1. Add a fix for a common resolution problem on retina devices in your startup code. Commonly this goes into your first scene (We usually have a Startup.cs file on the first object in the hierachy).

#if UNITY_STANDALONE_MAC
if (Screen.fullScreen){
      var resolutions : Resolution[] = Screen.resolutions;
      if (resolutions.length && resolutions[resolutions.length - 1].width > 2048){
          Screen.fullScreen = false;
          yield;
          Screen.fullScreen = true;
          yield;
      }
  }
#endif

UnityScript (adapted from the manual)

IEnumerator MacResolutionFix(){
#if UNITY_STANDALONE_MAC
    if(!Screen.fullScreen){ yield break; }
    Resolution[] resolutions = Screen.resolutions;
    if(resolutions.Length > 0 && resolutions[resolutions.Length -1]. Width > 2048  ){
          Screen.fullScreen = false;
          yield return new WaitForEndOfFrame();
          Screen.fullScreen = true;
          yield return new WaitForEndOfFrame();
    }
#endif
}

Void Awake(){ StartCoroutine(MacResolutionFix()); }

Our C# translation


2. Go to your Standalone Player Settings and enable "Mac App Store Validation". You'll find the options Under The Resolutions and Settings Panel.

3. Go to the Build Settings and Build your app. Make sure the name of your app is the same as used in your iTunes Connect profile. Otherwise your app will be rejected in app review!

4. Now we need to update our Info.plist manually. Unity will generate a template version for us. Go to the .app package and open it with "Show Package Contents". Open Info.plist in your favorite Text Editor. See the official guidelines (CoreFoundationKeys, LaunchServicesKeys).

<key>CFBundleDevelopmentRegion</key>
<string>{YOUR REGION}</string>
<key>CFBundleGetInfoString</key>
<string>{DESCRIPTIVE INFO}</string>
<key>CFBundleIdentifier</key>
<string>com.{YOUR COMANY}.{YOUR APP NAME}</string>
<key>CFBundleName</key>
<string>{YOUR APP NAME}</string>
<key>CFBundleShortVersionString</key>
<string>{VERSION NUMBER, e.g. 1.0.0}</string>
<key>CFBundleSignature</key>
<string>{4 LETTER CREATOR CODE, e. g.:  GMAD }</string>
<key>CFBundleVersion</key>
<string>{VERSION NUMBER, e.g. 100}</string>

These entries need your attention.

<key>LSApplicationCategoryType</key>
<string>{VALID APP CATEGORY, e.g.: public.app-category.kids-games }</string>

Add this key to the list. Looks like Unity forgot about this one!


5. Save the Info.plist inside your package and don’t forget to create a copy since Unity will overwrite the file the next time you make a build!

6. Navigate to the Resources folder inside your .app package. There should be an .icns file (mine was called PlayerIcon.icns). It contains the wrong icon sizes for the Mac Store so we have to build our own set.

Filename Pixel size
icon_512x512@2x.png 1024 x 1024 @ 144 dpi
icon_512x512.png 512 x 512 @ 72 dpi
icon_256x256@2x.png 512 x 512 @ 144 dpi
icon_256x256.png 256 x 256 @ 72 dpi
icon_128x128@2x.png 256 x 256 @ 144 dpi
icon_128x128.png 128 x 128 @ 72 dpi
icon_32x32@2x.png 64 x 64 @ 144 dpi
icon_32x32.png 32 x 32 @ 72 dpi
icon_16x16@2x.png 32 x 32 @ 144 dpi
icon_16x16.png 16 x 16 @ 72 dpi

All the required files for your iconset.

Generate all image files and put them in a folder. Name the folder like the .icns file in your app package and use .iconset as the extension (we now have a folder called PlayerIcon.iconset). Now we need to convert the folder into a real icon set. Fire up your terminal, navigate your .iconset folder and perform the following command:

iconutil -c icns "{ICONSET NAME, e.g.: PlayerIcon}.iconset"


You should end up with a new .icns file. Overwrite the .icns file in the package with the created one.

7. (Optional) Overwrite the default UnityPlayerIcon.png also found in the Resources folder with your own image.

8. Fix read permissions on all the content in your .app package. In the Terminal type:

chmod -R a+xr "{YOUR APP NAME}.app"


9. Next we’ll need to create an .entitlements file. For convenience, name it like your .app package. Open the file in your favorite text editor and copy the following snippet into it:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>com.apple.security.app-sandbox</key> <true/>
    </dict>
</plist>


This is the most basic .entitlements file with near zero capabilities. It worked for our app, because we didn’t need anything special. It might not work for you!

If it doesn't work for you: Unity mentions the Unity Entitlements Tool to easily generate an .entitlements file but the link in the manual is broken. After some search: Here is the download link for the latest version . Luckily I didn't need to use it for our little app, so good luck to you! Make sure you read the guide!

Save the file with the .entitlements ending, for convenience it should be located besides your .app package.

10. Next we’ll need to sign our app. It’s important you have the correct certificate - "Mac App Distribution" - in your keychain. Fire up the terminal again and navigate to the folder of your your .app package. Then type the following command to sign the package:

codesign -f --deep -s "3rd Party Mac Developer Application: {YOUR COMPANY NAME}" --entitlements "{YOUR APP NAME}.entitlements" "{YOUR APP NAME}.app"


Double check that you used the correct profile name! Even a missing space will make the command fail (our correct company name was: "gentlymad UG (haftungsbeschraenkt) (XXXXXXXXX)"). See your keychain and copy the profile name from there. Also, something the Unity manual doesn’t tell you: Use the --deep parameter to make sure to sign everything in the package.

11. Next we’ll need to build our package. Again, make sure you have the correct profile. This time we need: "Mac Installer Distribution" in your keychain. In the Terminal we’ll fire the following command:

productbuild --component "{YOUR APP NAME}.app" /Applications --sign "3rd Party Mac Developer Installer: {YOUR COMPANY NAME}" "{YOUR APP NAME}.pkg"


12. Start the Application Loader. Click on choose and select the newly created package. If you want to get feedback on the status of your app, go to "Window > Lookup Status…" and type in your SKU/vendor id. You'll see a small list about the status of the import process.

13. Wait for Apple to review your build > ??? > Profit.

Hope this helps you guys out when building for the Mac store. Please leave a comment if you come across any issues!

Cheers,
Matthias

Update 13/05/2016

Just found the following shell script that should ease things considerably. https://github.com/DaVikingCode/FromUnityAppToMacAppStore

The year 2015 in review