The AppStore certificates jungle
To all the mobile native devs... I feel your pain. Only we know what does it mean to manage the certificates of an iOS application
Well, a lot happened since my last post.
I missed writing here, but due to some circumstances and a global pandemic, I haven't been able to put the time in the writing of some articles for my own blog.
During the Italian lockdown, I did some video interviews and video chat though with the italianCoders group to entertain the Italian devs and in the meantime, as you can see, I took some time to refresh the UI of my website.
Having said that, let's see what we're going to talk about today, a topic I'm sure many of you are interested in mainly because, like me in the past, it's something you've always done while complaining about how hard it is (if you're mobile devs) and without understanding much... I'm talking about the process of creating the certificates and profiles necessary to develop and release an app on the Apple AppStore.
The difficulties, of course, don't come only from not understanding the process behind the signing, but also from the developer.apple portal which keeps changing UI and hiding stuff that instead should be highlighted. And to make things worse, it gets even harder when you have to build the app with the three common envs: development, staging, and production.
Why not use the automatic code signing?
Well you know, in the end, it all comes down to how confident you wanna be with the things you work with and also how much control you want. As a metaphor, there is the classical "manual vs automatic car transmission" dilemma which is very representative I think.
Also, I've never found any info about the automatic signing tool and so questions arise when the dynamics are a bit more complex. For example, if a team is developing an app, and everyone uses the automatic signing, what happens to the ios distribution cert which requires the correct private key that Xcode doesn't store on the servers automatically? (more on later if you didn't understand this).
And the continuous integration? Do the cli tools to build apps still work with automatic signing? etc. etc.
What always helps me is to have a simple but clear view of the parts in-game when signing an app. So we have:
- Identifiers (also called App Ids)
- Profiles (also called provisioning profiles)
- Development devices (also called "Testers")
And, before continuing, always keep in mind that for every little, stupid, insignificant thing you have to do, Apple wants you to sign it somehow. Either you have to test the application within an iPhone or you have to distribute the app from a private server (also called enterprise distribution), you need to sign the code you write.
There are many certificates type. Following the way they're listed on the apple portal, we have:
- Software certificates
- Services certificates
The software certificates are those that let you sign the code (or apps) you write. Some are specifics for macOS, some for iOS but there are also the broader certificates that can be used for both. The main two types here are:
- Development: certificates for running on development devices*. These are not good for firebase app distribution or test flight.
- Distribution: certificates for doing everything. Things such as test flight distribution, app store publication, enterprise distribution, etc.
The services certificates are self-explanatory. The most used is, of course, the push notification certificate. The one important thing to say is that they're tied to a specific App ID.
* The development devices I'm talking about are the ones listed inside the apple portal
Now, this might be the most obvious thing on the list, but I assure you it's not.
Basically, when you create an app, you need to create an App ID for it and the majority of times one enters this section just to create it.
For this reason, every developer maps in his head an App ID to an application, but what if I tell you that a single app can correspond to multiple App IDs?
This is the case when configuring service extensions for push notifications. In that case, we must create two App IDs, one for the app itself and one for the service extension.*
* Pay attention: even if you have a service extension App ID, the apple push certificate has to be tied to the main App ID
Here we are!
For devs, these are the most confusing in the apple signing process.
Substantially the main thing you need to think about right now, is that the certificates we talked about above have no intrinsic connection with any particular app id, in fact, you should use the same for every app you want to publish.
In addition, Xcode doesn't know what certificate has to be used on our app/scheme/extension (plus everything else needs a certificate).
So this is the reason profiles exist. Now what kind of profiles exist and for what precise reason are they used? These are the profile types (you may notice that there isn't a one to one match with the certificates types, keep in mind that for ad-hoc distribution you'll always need a distribution certificate):
- Development: it does two jobs; ties an app id to a development certificate and maintains a list of devices* where this app can be installed. As we said earlier for the certificate, we're only talking about the installation performed by Xcode during development.
- Ad Hoc: it does two jobs; ties an app id to a distribution certificate and ** maintains a list of devices*** where this app can be installed. This time we're talking about an installation performed from elsewhere, through a personal server, or a service like firebase app distribution.
- App Store: it does two jobs; ties an app id to a distribution certificate and allows you to upload that app on the app store (or test flight)
* These devices are listed (and can be added from) inside the very same portal
Nothing too fancy going on inside the devices tab. Here you'll find a list of the devices added in your apple developer account enabled for the "ad-hoc" and "development" installation processes of your app. These, as we saw, are listed and specified inside the profiles. To add one, you need the UDID of the device you want to add.
I'll remember you, once again, that these devices have nothing to do with TestFlight. If you use test flight, you won't need to register any device, since you can upload to test flight only with a distribution certificate and distribution provisioning profile.
Continuing the discussion about the service extension, that, of course, needs its own profile too. It's not written much about online sadly, but when you add one, its id in Xcode must be configured properly (meaning that if your app id is com.myapp.staging, the service extension must be com.myapp.staging.serviceExtension) and you need to generate a provisioning profile for that too that maps a distribution or development certificate to it.
Important note (recap)
If you wanna correctly configure all the three usual schemes, such as "dev, staging, and production" for the app you're developing, you'll generate:
- 1 to 2 certs: distribution and development (only if you want/need to start your app on a physical device).
- 1 to 3 profiles: dev (same exception), ad-hoc (only if you wanna use things such as firebase distribution, etc.), and distribution.
- 1 to 3 App IDs: dev, staging, and distribution. Different App IDs are needed just to allow you to have installed the three versions contemporarily on a single device. You could also create just one App ID, but still, you'd need to create three profiles to be able to do what we said in the previous paragraph.
As a rule of thumb, for every App ID, you need at least one profile for sure.
In the end, imagine what does it mean to configure the three stages when you have a service extension...