Workflow to automate and guide people in delivering Unity builds inside or outside of the Appstore.
CAUTION building for outside the Appstore may still need some work.
For a first build just follow all the steps. In each folder you will find instructions to deal with the problem at hand in chronology. After you finished the steps a first time you can just run “RepeatForUpdatedBuild” to quickly repeat the whole process. But you need to finish the steps so all the data used is correct otherwise problems will arise.
If you already have all the necessaries you can place them in their respective directories, following the table below and run “RepeatForUpdatedBuild”. The development profile is placed in the Appstore dir, because you only need it to test Appstore features.
All scripts (and todos) are described in more detail in each folder. As everything is automated there are also failsafes in place for overwriting or to check if needed files are present. We will not describe all of those, but you can view the script to see what is happening.
Creates PlayerIcon.icns & UnityPlayerIcon.png from single png file and placed them in BUILD/Contents/resources/
Script to Delete meta files in “BUILD/Contents/Plugins/plugin_x”
Info.plist is copied from “BUILD/Contents/” to “4_InfoPlist/” so you can update it manually once and reuse it after.
Copies your manually updated Info.plist from “4_InfoPlist/” to “BUILD/Contents/”
Opens all bundles in the plugins folder and replaces the BundleIdentifier value with yours (taken from “4_InfoPlist/Info.plist”).
Script that calls all the other scripts to speed up preparing updates and creating new builds.
As we will not be constantly uploading games to the App Store it might be good to have other people pitching in so that there’s a central point to get help that doesn’t age. So anyone who wants to become a contributor just pm me on git even if it is to just add some documentation.
We do not take credit for anything besides creating this workflow, tying the code we found together in bash with added automation and organising & rehashing documentation. Below are the credits for all the posts, threads we used. If we missed a spot please contact us.
We created this workflow because delivering a Unity build to Apple is a mess and the answer is spread across several websites which makes it hard to wrap your head around the correct final chronology especially if you’re new or on Windows.
There are tools out there like Signed that will also take care of some of this, but often it’s better to understand and not depend upon 3rd party assets, especially when things go wrong. We have tried to include paths, actions and DIY as much as possible so you can understand what’s happening and where everything is supposed to go.
|N3uRo||UNITY THREAD||Unity Assetstore Page|
|Victor Leung||MEDIUM GUIDE||..|
|JoeStrout||POST BUILD,SIGN, ZIP||Stroutandsons.com|
Worked on this workflow? Add yourself! Btw you can use the “doc/CombineAllReadmeIntoDoc” to recompile all readme’s for the online manual page.
Just place this workflow somewhere outside of your Unity project.
If you do not already have one go to Apple Developer portal and pay 100$ to get confused by professionals. And you might as well enable AUTO RENEW in the membership tab at Apple Developer portal. So you avoid surprises.
SELLING ON APPSTORE? If you are not releasing a free app/game and want to get paid outside of the US? Go fix the banking and tax first at Appstore Connect » Agreements, Tax and banking. It’s not necessarily something that has to happen now, but get it over with if you are about to release. Prepare for some serious legal and tax lingo.
Go to the Apple Developer Portal and create your certificates. Depending on where you want to release your game your need different certs. These serve as an identity that will be added to your iCloud keychain and allow you to codesign and create your provisioning profiles later. More on certificate names
IMPORTANT In the creation process the field “common name” will name your keychain. Make sure you name your certificates in a way you can recognise them later. Its not a disaster if you don’t but it does make your keychain a bit more clear if problems arise later. So for example “TEAM_Mac Installer Distribution”.
IMPORTANT Always make sure you use the correct certificates and provisioning profiles. If you have signed your app with old certificates (and provisioning profiles) you will need to download these again from the member center. CREDIT Atorisa
Apple Developer Portal Go to App Identifiers. Examples : COM.COMPANY.PRODUCT, UNITY.COMPANY.PRODUCT, … It’s up to you. Note that you cannot disable In App Purchase. IAP is always enabled, but if you don’t implement any button or script in Unity you can just ignore this. More info on bundle identifiers here
Go to iTunes connect and create a new OSX app.
QUOTE Victor Leung Login to iTunes Connect, choose My Apps > “+” > “New Mac App”, fill in the values and choose the bundle ID matches with the previous step. The prefix field would be the game name, such us ufo in my case.
The type of provisioning profile depends on your selling platform (in -or Outside Appstore). To test Appstore features like Game Center you will need to create a separate provisioning profile for Appstore development as the distribution build will not allow testing.
|FOR||NAME PROVISIONING PROFILE|
|Testing||Mac App Development|
|Distribution Appstore||Mac App Store|
|Distribution Outside Appstore||Developer ID|
Go to the Apple developer portal. Just follow the instructions, if you have more problems follow this tutorial. Also give a clear name to your profiles when you download them so you do not make mistakes later.
you will be asked to add a device and give the UUID of this device you can find this here: About this Mac > System Report > Hardware overview (Hardware UUID: XXXXXXXXX)
These will be copied later into your app as embedded.provisionprofile ( dependant on the build you chose).
QUOTE “Zwilnik @ Strange flavour” Another key step is to include a copy of the provisioning profile in the app bundle before signing it. It goes in the app bundle at Contents/embedded.provisionprofile. Again, this is something Xcode would do for you normally that you have to do manually when building with Unity. Do this for both development and distribution builds including the correct development or distribution profile.
You will also need it to open your .plist files later. Or alternatively to create your icon without the scrips.
Add to any GO that will live @ startup to fix retina on large screens.
If you want to build for outside the Appstore, make sure you uncheck Mac Appstore validation in your build.
You can enter all of the other OSX values later in your Info.plist which is more typo proof as it has dropdown for certain values.
So that’s “1_MyBuild/MYGAME”
If you have created an PlayerIcon.icns & UnityPlayerIcon.png and want to use those just put it them in the folders described below and Run “OSX Icon” to copy them to Contents/resources in your build.
Either use this icon as a base or:
On High Sierra there is no way to create an icns file that includes all 10 required sizes through icon util (Everything but 16X16@1x and 32x32@1x). The only way to do this is to run this script on an older OS. I believe I did it with Sierra. You can open .ICNS files with preview to double check. I am not sure if this is a problem though. I have read not all are necessary. But if you are obsessive on details like me there is no other way. Believe me I have tried it all. Nothing worked besides running the IconUtil on an older OS.
|email@example.com||1024 x 1024 @ 144 dpi|
|icon_512x512.png||512 x 512 @ 72 dpi|
|firstname.lastname@example.org||512 x 512 @ 144 dpi|
|icon_256x256.png||256 x 256 @ 72 dpi|
|email@example.com||256 x 256 @ 144 dpi|
|icon_128x128.png||128 x 128 @ 72 dpi|
|firstname.lastname@example.org||64 x 64 @ 144 dpi|
|icon_32x32.png||32 x 32 @ 72 dpi|
|email@example.com||32 x 32 @ 144 dpi|
|icon_16x16.png||16 x 16 @ 72 dpi|
The script will go into “1_MyBuild/YOUR.APP/Contents/Plugins” and find & delete any “.meta” files in your bundles.
Every time you build Unity adds meta files to the plugins which give problems if they get signed.
CREDIT / QUOTE “Zwilnik @ Strange flavour” Firstly, as I mentioned, Unity has an annoying issue with its file system. Anything in your project folders gets a .meta file created for it (I’m assuming to help track it within the Unity editor). This is normally fine as long as you remember to build your target app outside your project folder, except for when you use any plugins..
Because your plugins are stored within the project folder, their bundle files all have .meta files in them. When it comes to signing, these meta files break the signing and as they’re data files in the root of the bundle (which is bad).
Open “YOUR_BUILD/Contents/Plugins/” open each bundle and delete all the meta files in there.
Will take the Info.plist from 1_MyBuild/YOUR.APP/Contents/Info.plist and paste it here. If there is already one in this folder it will make a backup copy just to be sure.
Don’t open in an editor, just double click and open with Xcode so you have access to the dropdown values to avoid typo’s.
In the examples folder you can find an empty example (that we used) for reference.
|Bundle identifier||COM.COMPANY.APPNAME Its the one you created in the beginning in the Apple Developer Portal|
|Bundle name||App name|
|GetInfoString||The copyrights to your game instead of Unity’s|
|ApplicationCategory||Your category In Unity 2017.3 this seems to be ok, but you can avoid typo’s using the dropdown|
|Localization native development region||The development language of the bundle.|
|ShortVersionString||Version Build or version number should always be increased each time you upload to the Appstore as you cannot upload a package with identical version & build More on Version & build|
|BundleVersion||Build number. Used to upload packages to the Appstore that you do not want to show in your public version. Can be the same as ShortVersionString, but if you want to change your screenshots at the Appstore you will need to send them a new package, with build you could hide this new version without increasing your version number.|
|App Uses Non-Exempt Encryption||TRUE/FALSE - A.K.A “App is using encryption that is exempt from EAR” Before you scare read Short answer, this for Unity, and this by Unity|
|CFBundleSupportedPlatforms||MacOSX Without this the application loader seems to default to iOS. Read More by N3uRo|
Will replace the Info.plist in your build with the one you just made.
Takes the Info.plist you just made and finds your BundleIdentifier. Opens all bundles in the plugins folder and replaces the BundleIdentifier value with yours.
Every app and plug-in uses an Info.plist file to store configuration data in a place where the system can easily access it. macOS and iOS use Info.plist files to determine what icon to display for a bundle, what document types an app supports, and many other behaviors that have an impact outside the bundle itself. More info on Info.plist @ Apple
Change it and basically describe what your app will need. At the very least it always needs com.apple.security.app-sandbox set to yes.
|com.apple.application-identifier||TeamID.COM.COMPANY.GAME||If Game Center,…?|
|com.apple.developer.team-identifier||TeamID||If Game Center,…?|
|com.apple.security.network.client||YES||If accessing things online|
When you sign your code you need to add the correct entitlements, meaning you describe what you will access and need or in other words what the app can be expected to do. Codesign will use this information in the signature.
connect to outside websites, use camera, access public folders like Pictures, …
QUOTE Matthias @ GentlyMad (Entitlements file with only com.apple.security.app-sandbox.) 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.
QUOTE Zwilnik @Strangeflavour As the game’s going to work on Yosemite and Mavericks and be downloaded from the Mac App Store it MUST have the App Sandbox enabled. This protects users from any bugs in your code accessing and breaking things it shouldn’t. However it does mean you have to specifically add any features your app needs.
QUOTE Zwilnik You’ll need the App Sandbox entitlement (set to YES) and if you’re accessing anything on the internet, you’ll need com.apple.security.network.client set to YES too To cover Game-Center you have to manually add the following entitlements in your entitlements file (normally Xcode would handle this for you..) com.apple.application-identifier & com.apple.developer.team-identifier
Create your entitlements file and place it in the same folder as your build. You could place it anywhere you just have to reference the correct folder when you call codesign in the terminal.# Sign, package build & Deliver
From your keychain. Looks like this “TEAM NAME (XXXXXXXXXX)” Where the XXXXXXXXXX is your team id. Copy it exactly as it is, so no spaces before or after. Example where to find
Like in the previous chapter go to Membership and copy your team name and team ID there and put it in this format: “TEAM NAME (XXXXXXXXXX)”
IMPORTANT If your team name has spaces in it they also have to be included. So full team name including spaces then again a space after and then in between parentheses your team id. Ok three examples:
|INPUT||WILL CREATE PACKAGE FOR||AT|
|outside||Distribution outside Appstore||7_Distribution/Outside Appstore/CHOICE/VERSION/|
IMPORTANT if signing is successful and you have signed for the first time you will be prompted to add “codesign” to your keychain. Always allow
Reads your new Info.plist and finds version & build to create a final folder based on your values so you can keep track of which builds were made for what. If you use the same value for build & version only version will be used, otherwise it will create a folder named “VERSION”+b+”BUILD” (e.g. 1.0b0).
Depending on your choice between appstore, dev or outside the correct provisioningprofile will be copied to your game as “embedded.provisioningprofile“
NOTE That when zipping your build this profile will not be included as I am not clear yet if this is required.
All code needs to be signed for your app to be approved. Sometimes –deep does not work so we manually sign all the code we (know) and loop over all the .bundles in your plugin folder. For us this worked out, but if you know of more generic libraries that should be added please let me know.
|all .bundle files in /Contents/Plugins/ are signed iteratively|
|Your app will be signed with –deep ( all subfolders)|
See if everything worked out.
When creating any installer make a duplicate of the correct provisioning profile, rename it to embedded.provisioningprofile and place it in YOUR_BUILD/Contents. Read more at Strangeflavour
In this order
codesign --entitlements "DIR_Entitlements" --deep --force --verify --sign "3rd Party Mac Developer Application: TEAM NAME (TEAM_ID)" "appDir"
codesign --deep --force --verify --sign "3rd Party Mac Developer Application: TEAM NAME (TEAM_ID)" "appDir"
codesign --entitlements "DIR_Entitlements" --deep --force --verify --sign "Developer ID Application: TEAM NAME (TEAM_ID)" "appDir"
|–deep||Go through all subfolders to sign everything|
|–force||Resign everything that has been signed|
|–verify||See if things got signed|
|–entitlements||Location of your entitlements|
|–sign||The type of signing with your team name|
productbuild --component “$appDir” “/Applications” --sign "3rd Party Mac Developer Installer: TEAMNAME (TEAM_ID)" "$appName.pkg
productbuild --component “$appDir” “/Applications” --sign "3rd Party Mac Developer Installer: TEAMNAME (TEAM_ID)" "$appName.pkg
productbuild --component “$appDir” “/Applications” --sign "Developer ID Installer: TEAMNAME (TEAM_ID)" "$appName.pkg
When Installing the installer will default to the directory of your build. e.g. /1_MyBuild/App and not the application folder. So either test the application from here or if you want your testing build in the applications folder, delete your build before installing your final pkg.
Open your game and check the logs (Applications > Utilities > Console) for errors and use that as reference to Google yourself out.
QUOTE “Zwilnik @ Strange flavour” When you launch the game, you should see a dialog pop up that tells you that the game was purchased by a different account, so you need to sign in with one of your Mac App Store Sandbox test IDs here for the game to launch. Don’t use your normal login, it must be a Sandbox ID
If you cannot open your build it’s possible you forgot to uncheck “Mac Appstore validation” in the player settings when you made your Unity build.
QUOTE Mark-ffrench Installing the pkg file should, in theory, install the app in the /Applications folder. However, there are a couple of other possible issues that you might encounter:
If OSX already thinks you have a copy of your app anywhere on your mac, it will install your new version over it. This could be anywhere on your hard drive, so make sure that the app you are trying to run after installation is the one that has actually been updated by the installer. Your best bet is to try track down all copies of your app and delete them.
Fill in the details for your App such as description, keywords,… Make sure here you DO NOT reference other platforms.
Quote Victor Leung After filling in the form, you will also need to spend some time to take screenshots, and crop them in the right size. Only the following sizes are allowed:
IMPORTANT Once you upload your build for review with your screenshots, those screenshots are stuck. Meaning you need to upload a new build to replace the previous screenshots.
In Xcode Top Menu “Xcode” > Open Developer Tools > Application loader.
Dilmer Valecillos told of a problem with newer versions of Application Loader, but we didn’t have this problem. The opposite actually, we weren’t able to open application loader 3 getting this error: “To use this application, you must first sign in to Itunes Connect and sign the relevant contracts.” Which we couldn’t fix, but we could just do it with Xcode’s default Application loader. Though if you need it: Download link application Loader 3.0
Go to Itunes Connect > Your App > Activity and check if your build is there. After uploading a build it can take 15 minutes to 1 hour (or longer) to finish processing in Appstore connect.
Now open the Prepare for submission (in the Appstore tab of Your game/app). Select your build, fill in the contact info and click on Send for review.
Is your app designed to use cryptography or does it contain or incorporate cryptography? (Select Yes even if your app is only utilizing the encryption available in iOS or macOS.)
Does your app contain, display, or access third-party content?
The review process can go from a few hours up to 7 days depending on the complexity of your game and some other factors like Christmas.
If you upload a new package to the Appstore after a rejection, you will not be able to reply on the previous answer of Apple. So if there are things you need to tell/ask the Review people do it when your App gets rejected in Appstore Connect.
QUOTE “Victor Leung” If you got an email with issues, Invalid Signature — The main app bundle game at path GAMENAME.app has following signing error(s): invalid Info.plist (plist or signature have been modified) In architecture: i386 . It is probably one of your subcomponent didn’t sign correctly, which you may need to spend sometime on Apple documentations to understand how it works.
Don’t worry you don’t need to go through everything again. You just run RepeatForUpdatedBuild and it will go through all the steps with the data you used. But don’t forget to increase the version or build number in Info.plist for a new build.