Entitlements are Apple's mechanism for declaring which system capabilities an app is allowed to use. They live in an `.entitlements` XML plist next to your project, get baked into the code signature at build time, and have to be granted by a matching provisioning profile or the OS will refuse to enable them at runtime.
Capabilities that go through entitlements
- Push notifications (`aps-environment`).
- App Groups (`com.apple.security.application-groups`).
- iCloud containers and CloudKit (`com.apple.developer.icloud-container-identifiers`).
- HealthKit, HomeKit, ClassKit, WeatherKit, WalletKit.
- Sign in with Apple (`com.apple.developer.applesignin`).
- Associated Domains for universal links (`com.apple.developer.associated-domains`).
- Network Extensions and Hotspot Helper.
- Mac sandbox switches (`com.apple.security.*` family).
How they tie to provisioning
An entitlement in your .entitlements file only takes effect if the provisioning profile that signed the build authorizes it. Enabling push in Xcode adds the entitlement to the local file, but you also have to enable push on the App ID in the Apple Developer portal and regenerate every provisioning profile that uses the App ID. Forgetting that last step is the most common cause of 'app installs but push tokens never arrive' bugs.
Three flavors that confuse people
- Development
- Push uses `aps-environment: development` and the sandbox APNs server. Signed by an Apple Development certificate.
- Distribution
- Push uses `aps-environment: production` and the production APNs server. Signed by an Apple Distribution certificate.
- Capability vs entitlement
- A capability is the toggle in the Apple Developer portal and Xcode UI. The entitlement is the resulting plist key and value. The portal-side capability has to match the project-side entitlement.