Understanding Entitlements
Entitlements are the bridge between products (what users buy) and features (what users get). Instead of checking individual product IDs, you check entitlements to determine feature access.
Why Entitlements?โ
Without entitlements, you'd need to check every product that could grant access:
// Without entitlements (fragile)
if hasProduct("com.app.monthly") || hasProduct("com.app.annual") || hasProduct("com.app.lifetime") {
showPremiumContent()
}
With entitlements, you define the mapping once and check a single key:
// With entitlements (clean)
if customerInfo.entitlements["premium"]?.isActive == true {
showPremiumContent()
}
Product โ Entitlement Mappingโ
You map products to entitlements during configuration. Multiple products can grant the same entitlement.
Payment Modeโ
In payment mode, entitlement mappings are configured on the server via the AppActor dashboard. The SDK fetches them automatically.
Local Modeโ
In local mode, you define the mappings in your configuration:
entitlements: {
AppActorEntitlementDefinition("premium", productIDs: [
"com.myapp.monthly",
"com.myapp.annual",
"com.myapp.lifetime"
])
AppActorEntitlementDefinition("pro", productIDs: [
"com.myapp.pro.monthly",
"com.myapp.pro.annual"
])
}
Entitlement Stateโ
Each entitlement has a rich state that reflects the underlying subscription:
| Property | Type | Description |
|---|---|---|
isActive | Bool | Whether the user currently has access |
productID | String? | The product granting this entitlement |
expirationDate | Date? | When access expires (nil for lifetime) |
willRenew | Bool | Whether the subscription will auto-renew |
isInGracePeriod | Bool | Payment failed, in Apple grace period |
isInBillingRetry | Bool | Apple is retrying the payment |
isRevoked | Bool | Subscription was refunded/revoked |
ownershipType | OwnershipType | .purchased or .familyShared |
periodType | PeriodType | .monthly, .annual, .lifetime, etc. |
Merging Logicโ
When multiple products grant the same entitlement (e.g., both monthly and annual grant "premium"), the SDK uses this priority:
- Active wins over inactive โ If any product is active, the entitlement is active
- Later expiration wins โ If multiple products are active, the one expiring latest is used for metadata
Next Stepsโ
- Checking Status โ Patterns for checking entitlement access in your app