Submitting Unity apps to the iOS App Store
- 30. June 2016
Submitting Unity apps to the iOS App Store
If this is your first time building an Unity project for the iOS App Store, prepare for a long and winding road. Before we begin, a word of warning: If you are reading this post months or years after it has been published, there is a pretty good chance that some of the attached screenshots are outdated. The UI of XCode and the iTunes Connect page is being reworked on a regular basis. The naming of some elements like menu entries or button labels may also have changed by then.
There are some prerequisites for submitting an app to the iOS App Store. You will need:
- a Mac (or a PC that simulates a Mac, but I won't get into that)
- a current version of XCode, which you can get from the Mac Store for free
- at least one target device to test the app before submission (e.g. an iPad Air 2)
- an Apple ID including an active iOS Developer Program subscription (which costs 99 USD / year)
If your developer subscription expires, published apps will no longer be available for download from the App Store, so you'll have to renew your subscription each year.
1. Certificates, Identifiers and Profiles
Let's get started by preparing everything for the Store submission - and there is quite a bit to prepare! Our first stop will be Apple's Member Center. Log in with your Apple ID and go to "Certificates, Identifiers & Profiles". If your Apple account is part of more than one developer team, you may have to choose the correct team first (the one publishing the app).
1.1 Create a Distribution Certificate
If you have never before published for the App Store or if you are building on a new Mac, you have to create a Distribution Certificate first.
- Go to "All" under "Certificates" to create a new certificate (by pressing the "+" button).
- Select the certificate type "App Store and Ad Hoc".
- At the next step, Apple gives very handy instructions on how to generate the required Certificate Signing Request (CSR) file on your Mac (also see the screenshot below).
- After generating the CSR file, you will have to upload it to the Member Center. Afterwards you can finally generate the Distribution Certificate.
1.2 Create an App ID
- Go to "All" under "Identifiers" to create a new Identifier (by pressing the "+" button).
- Add a description (i.e. the name of your app). Some characters like underscores or minuses are not allowed.
- Select the correct prefix (i.e. Team ID).
- Enter a suffix (i.e. your app's bundle ID). Again, some characters like underscores (but not minuses this time) are not allowed. The suffix is how Apple identifies your app. Keep in mind, that you have to use the exact same bundle ID as in your Unity/XCode project. Typically, you use a reverse-domain name style string, so it is unique: com.companyname.appname
1.3 Create a Provisioning Profile (optional)
This step is optional because by now, XCode has the ability to create profiles for you, depending on which kind you need. For publishing to the App Store, we need a distribution profile, so when you submit the app via XCode (we'll do this later), you can automatically generate a profile. If you want to do it manually anyway or if something goes wrong with the automated process, follow the next steps. Also: XCode names the profiles after a scheme "iOS Team Provisioning Profile: [app_bundle_id]". So if you create lots of profiles and do not want them all to be named similarily, you have to do it manually as well.
- Go to "All" under "Provisioning Profiles" to create a new Identifier (by pressing the "+" button).
- Select "App Store" under "Distribution".
- Select the App ID (sorted by Description i.e. app names) we created during the previous step.
- Select "Certificate (iOS Distribution Certificate)".
- Enter a meaningful Profile Name. I am currently using a combination of the app's name, the profile type and "Profile", e.g. "FancyApp_Distribution_Profile" or "FancyApp_Development_Profile". Since you may need to create more than one kind of profile per app, it makes sense to add the profile type to its name and not solely name the profile after the app.
- Download the profile and install it on your Mac (by executing the file). All profiles will automatically be synced with any connected devices. This is more relevant for Development Profiles, since they include a specification of which devices the app can be installed on.
Expired profiles won't affect your published apps on the App Store. However, if you want to submit an update, you will have to renew expired profiles. This can be done by editing the profile at the Member Center and selecting "Generate".
2. iTunes Connect (#1)
Next stop: iTunes Connect. This is where you upload your app to via XCode. We will now prepare the app's store page and come back later after the app has been uploaded to complete the submission.
- Go to "My Apps" and add a new app (by pressing the "+" button).
- Choose your target platform (iOS).
- Enter your app's name. This is the exact name, as it will appear on the App Store! You will however be able to change it before submission, so do not worry if you are not yet quite sure how to name your baby. This also applies to the primary language. Speaking of which:
- Choose your app's primary language.
- Select your app's bundle ID. You can only choose bundle IDs which have previously been created at the Member Center. This absolutely makes sense and prevents you from messing up by making a typo.
- Add an unique SKU (Stock Keeping Unit), e.g. a combination of date plus bundle ID. As far as I know, this ID is never again used or required. However it may be of meaning to your company if you want to use SKUs to keep track of you apps.
After creating your app's entry, you will land on your app's overview page. There you can fill in more information, most of which will be visible on the future store page of your app. Add all required information for version 1.0. This means adding at least one screenshot, a description, an icon, contact information and choosing whether or not your app should be automatically realeased after being granted approval (otherwise, you have the option to define a fixed release date). The only missing information should now be the build, which we will upload via XCode later.
I am assuming that at this point, you have created a complete application which is just waiting to be released for iOS. If this is not the case, go get to work!
3.1 Project settings
Double-check your project settings before building for iOS. You may consult the Unity manual for further information.
- Enter the correct company and product name. The product name will be your app's label on each device.
- Add an icon to represent your app. Ensure, that your icon does not include any text or that any text included is large enough to be readable on the target devices.
- Double- and triple-check your bundle ID. This ID must exactly match the one entered at the Member Center and iTunes Connect.
- Check your app's default orientation. For iPad apps, it's typically landscape left and should rotate automatically.
- Check your app's default resolution.
- Select your target devices (phones and/or tablets).
- Add a splash image which will be displayed on startup.
- Check the SDK version and stripping levels.
- Since March 2015, building for 64-bit capable devices is mandatory. Thus you must select "IL2CPP" as Scipting Backend and "Universal" Architecture.
3.2 Build settings
- Select the iOS platform.
- Make sure "Symlink" and "Development Build" are disabled.
Now you may proceed and build your application for iOS! The resulting files form an XCode project.
Open the previously generated file with the ending .xcodeproject with XCode. If you receive a warning about using external plugins, just ignore it and continue.
- Check the build settings and ensure that everything is set correctly.
- Select the correct developer team. This is only relevant if you are part of several iOS developer teams.
- Connect your iOS device to your Mac and test the app. The app will be built and run on the target device after you click the play-button. Make sure, that the correct device is selected in XCode.
- This is a critical point since errors may occur during the build process which could not be detected in the Unity Editor. You may have to do some research to find the culprit and fix the error.
- There is a bug in XCode (version 7.2.1), which stops the app on its splash screen and displays a bad access error during allocation (AllocateRenderBufferStorageFromEAGLLayer) in the log. However, this error will only occur if you try to run the app via the build and run function of XCode. If you disconnect the iOS device from your Mac and then start the app via clicking its icon, it will run just fine.
- Extensively test the app on your device and make sure everything works and looks as expected/intended.
- If you are content with the state of your app, we will proceed to upload the build to iTunesConnect. Select "Product" on the menu bar and "Clean" the project.
- Create an archive of the project (go to "Product" / "Archive" on the menu bar). Unfortunately, errors may occur during the archiving process as well. If you encounter an error, you will have to do some research to find out what's wrong and fix it...
- After the archive has been created, the archives overview window opens automatically.
- Select your app and go to "Upload to App Store". Follow the instructions of the dialog until you've completed the upload to iTunes Connect (or until an error occurs, in which case you will have to repeat the researching and fixing cycle).
- If uploading via the Organizer does not work, you may want to try your luck with the Application Loader instead. First export the archive from the Organizer by clicking "Save for iOS App Store Deployment". Then open the "XCode" menu on the menu bar, choose "Open Developer Tool" and go to "Application Loader". This alternate route once helped me to resolve issues with the uploading process caused by being linked to multiple developer teams.
5. iTunes Connect (#2)
Let's go back to iTunes Connect now and submit our app! You may have to wait a bit for your build to appear on iTunes Connect. You can check the status of your upload by going to "Activity" / "All Builds". In my experience, the upload process should take no longer than a few minutes. You will be notified via e-mail, once the upload has been completed, so there is no need to frantically press the F5 button.
- Go to your app's entry and find the "Build" section.
Select your uploaded build.
- This should have been the last missing piece! You are now ready to submit your app for review! Take into account, that the review process may take approximately one to two weeks. You will be notified via email as soon as your app has been approved and is ready for sale. Once you have submitted your app, you cannot modify its information (e.g. keywords), so make sure to double- and triple-check!
- Optionally, you may want to test your app prior to submission. This can be accomplished via TestFlight.
- Having your app selected in iTunes Connect, go to "TestFlight". Choose the preferred test type and add testers. This is app/build-specific. The difference between internal and external testing is that internal testing only works with Apple IDs. For external testing, you can use any email address for testers (no Apple IDs required). The advantage of internal testing is that you can skip the beta review altogether. However if you want to provide the test build to customers or a large group of testers, you will probably have to settle on external testing and bear with the review process. The following steps are based on the assumption that you chose external testing.
- After having added at least one tester, the "Add build to test" button will appear. Select the current build.
- Fill in the required information. A marketing URL is required, if you do not have one, just enter the URL of your company or something like that. This URL will only be visible to testers.
- At the next step, leave your contact information for the beta review.
- After submitting your build for beta review, the status will be changed to "Waiting for Beta App Review". This may take a while, especially if this app is being submitted for the first time. The last time, it took a little more than two days for me.
- After approval, you must select the approved test build and "Start Testing", which will notify testers.
Note, that test apps expire after 60 days and the testing process cannot be prolonged. If you want to provide the test build to testers after this period, you will have to upload a new version (and go through the beta review process again).
6. Publishing Updates
If you want to publish an updated version of your app, do not forget to increment the build number (integer) while the version number may remain the same! If you forgot to adjust the player settings in Unity, the build number can still be modified in XCode. To publish an update, you basically have to repeat the publishing process from Unity through XCode to iTunes Connect. In iTunes Connect, you just add a new version to your app's entry and prepare the Store Page.
If you've completed your iOS submission without encountering any obstacles, count yourself really, really lucky. Even after several app submissions, I still stumble upon new hindrances almost every time. For example, you will have to make sure that your Unity, XCode, Mac OS and iOS versions are compatible and may have to update any combination of them before you can even get started. The last time a colleague of mine wanted to submit an app, the iOS on our testing device had been updated and thus became incompatible with the XCode version on our Mac. But to update XCode, we first had to update Mac OS. That's all stuff, that consumes a lot of time (and nerves).
However, my favourite error of all times was when the "Apple Worldwide Developer Relations Intermediate Certificate" expired which apparently happens every seven years. Since I am not constantly building and publishing iOS apps, stuff like that catches me relatively unprepared. In direct comparison to publishing Android apps, Apple's process seems tiresome and frustrating. I often find the error messages cryptic and have to resort to the advice of the search engine of my choice.
On top of that, XCode itself often is buggy and Apple seems to have a fetish for reworking user interfaces which does not make a developer's life easier, especially if one's trying to stick to a manual. To give you an example of the constant revisions, XCode's "Submit to App Store" button has been renamed four times since I started documenting the publishing process twenty months ago (from "Distribute" to "Export" to "Submit" to "To App Store" to the current term).
- Build your Unity app for iOS.
- Run and test the XCode project on your device.
- Clean and archive the project.
- Upload to iTunes Connect via the Organizer.
- Prepare the Store Page on iTunes Connect.
- Submit your app for review!
- Wait for approval and publish your app.