Running an iOS app on a physical device requires two components: a signing
certificate and a provisioning profile. The signing certificate is issued
by Apple as part of their developer program and is used by the device to verify
the integrity and origin of the app before it is allowed to run. A provisioning
profile controls what devices are authorized to run the app and enumerates the
app’s entitlements.
The provisioning profile is also issued by Apple through the developer portal,
but developers can choose what devices and entitlements the profile authorizes.
More About Entitlements
Entitlements are special iOS features (such as Push
Notifications, Apple Pay, HealthKit integration, etc) which require special
configuration and authorization to use in an app. Enabling these features is
integrated with the code signing process because some entitlements can enable
communication and sharing of data with other apps, parts of iOS, or even
websites. Apple uses capabilities to protect potentially sensitive data form
being exposed to malicious apps. Integration with the code signing process helps
ensure that the app developer has full control over what data is allowed to be
shared and who/what it is shared with.
Certificates
There are two types of signing certificates:
Development and
Distribution.
Development Certificate
Each developer typically has their own development certificate which authorizes
them to deploy an app to a device from their own computer using Xcode. An app
signed with this certificate can only be deployed to a device by someone who
also has the matching private key. This makes builds signed with a development
certificate unsuitable for beta distribution because you should never
distribute your private keys.
Distribution Certificate
Apps signed with a distribution certificate can be installed on devices without
the matching private key which is why this kind of certificate is required for
App Store submission. This certificate type is also used when creating beta
releases on services such as HockeyApp. Unlike development certificates, only
one of these is used at a time (because of the 1-to-1 relationship with Release
and AdHoc provisioning profiles, which I’ll describe next). This certificate is
usually “owned” by the continuous integration server which automatically deploys
builds to HockeyApp, TestFlight, or the App Store.
Provisioning Profiles
There are three types of provisioning profiles:
Development, AdHoc, and
Release.
Development Profile
Development profiles include the list of devices used for development and
debugging with Xcode. Multiple development certificates can be linked to this
type of profile and each developer that will be working on the app needs to have
their development certificate added to the development profile. Any physical
device will need to be listed in the profile if you want to run or debug the app
on the device with Xcode.
While using a development profile, entitlements are automatically added to the
profile when you enable them with the *.entitlements
file within your Xcode
project. Note that when building an app with a development profile and
certificate, you are limited to using the sandbox push notification gateway.
AdHoc Profile
This profile is similar to a development profile in that devices must be added
to it to be able to run the app. However, when building with an AdHoc profile,
the app must be signed with the distribution certificate linked to the profile.
AdHoc profiles may only have a single distribution certificate associated with
them. Apps built with an AdHoc profile and signed with a distribution
certificate may be distributed to devices listed in the profile without having
to use Xcode or the private key.
Entitlements must be configured when issuing an AdHoc profile to match the
*.entitlements
file. If the entitlements in the AdHoc profile do not match
what is listed in the *.entitlements
file, the app will not be allowed to run
on a device. Apps built with an AdHoc profile may use the production push
notification gateway (in addition to the sandbox).
Release profile
When submitting an app to the App Store, you must build it with a release
profile and sign it with a distribution certificate. A release profile works
just like an AdHoc profile, with the exception that you do not need to add
authorized devices to it (because it will be eligible to run on any device when
downloaded from the App Store after release). Apps built with a release profile
cannot be installed on a device using Xcode or from services like HockeyApp. The
only way to install an app built with a release profile is to download it from
the App Store or the TestFlight beta program.
A Note About Apple Watches
If a device is paired to an Apple Watch, the watch must also be included in the
provisioning profile, otherwise the device will not be permitted to run the app.
Automatic Management with Xcode
Developers have lamented the complexity of the codesigning system in iOS for
years because managing certificates and profiles usually requires many trips to
your apple developer account console. Fortunately, Apple added
automatic code signing management to Xcode 8 at
WWDC 2016. By checking the
Automatically manage signing box in your project settings,
Xcode will generate signing certificates and provisioning profiles for you using
your developer account credentials. This is usually enough for many developers
but manual setup is still neccesary when adding devices to a profile that are
not linked to your developer account, or when using a signing identity from a
developer account that you don’t have access to.