一、什么是 Entitlements(授权)
Entitlements是苹果生态系统(iOS/macOS/tvOS/watchOS)中的一种权限机制,用于声明应用程序需要访问的受保护的系统资源或能力。
它本质上是一个XML 格式(plist)的键值对文件,在应用签名时嵌入到二进制中,由系统内核在运行时验证。
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPEplistPUBLIC"-//Apple//DTD PLIST 1.0//EN""http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plistversion="1.0"><dict><key>com.apple.security.app-sandbox</key><true/></dict></plist>二、Entitlements 的工作原理
- 开发者在 Xcode 中启用某个 Capability
- Xcode 自动生成
.entitlements文件 - 编译时通过
codesign命令嵌入到应用签名中 - App Store 审核 / 系统内核验证是否匹配 Provisioning Profile
- 运行时由
amfid(AppleMobileFileIntegrity)守护进程强制执行
三、Entitlements 分类详解
📱 1. App Sandbox(应用沙盒)- 仅 macOS
<key>com.apple.security.app-sandbox</key><true/>解释:启用后,应用被限制在一个隔离的容器中,只能访问被明确授权的资源。Mac App Store 应用必须启用。
🌐 2. 网络权限
<key>com.apple.security.network.client</key><true/><key>com.apple.security.network.server</key><true/>- network.client:允许应用发起对外的网络连接(如 HTTP 请求)
- network.server:允许应用监听端口,接受外部连接(如作为服务器)
📂 3. 文件访问权限
<key>com.apple.security.files.user-selected.read-only</key><true/><key>com.apple.security.files.user-selected.read-write</key><true/><key>com.apple.security.files.downloads.read-write</key><true/>- user-selected.read-only:用户通过打开面板选择的文件,只读
- user-selected.read-write:同上,可读写
- files.downloads.read-write:直接访问 Downloads 文件夹
🎥 4. 硬件设备权限
<key>com.apple.security.device.camera</key><true/><key>com.apple.security.device.microphone</key><true/><key>com.apple.security.device.usb</key><true/><key>com.apple.security.device.bluetooth</key><true/>- camera:访问摄像头
- microphone:访问麦克风
- usb:访问 USB 设备
- bluetooth:访问蓝牙
⚠️ 注意:除了 entitlement 之外,还需要在Info.plist中添加Usage Description(如NSCameraUsageDescription)。
👤 5. 个人信息访问权限
<key>com.apple.security.personal-information.location</key><true/><key>com.apple.security.personal-information.addressbook</key><true/><key>com.apple.security.personal-information.calendars</key><true/><key>com.apple.security.personal-information.photos-library</key><true/>- location:定位
- addressbook:通讯录
- calendars:日历
- photos-library:相册
☁️ 6. iCloud 相关
<key>com.apple.developer.icloud-container-identifiers</key><array><string>iCloud.com.example.app</string></array><key>com.apple.developer.icloud-services</key><array><string>CloudKit</string><string>CloudDocuments</string></array><key>com.apple.developer.ubiquity-kvstore-identifier</key><string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string>- icloud-container-identifiers:iCloud 容器 ID
- icloud-services:启用的 iCloud 服务(CloudKit / iCloud Drive)
- ubiquity-kvstore-identifier:iCloud 键值存储(NSUbiquitousKeyValueStore)
🔔 7. 推送通知
<key>aps-environment</key><string>development</string><!-- 或 production -->解释:启用 APNs 推送。development用于开发调试,production用于 App Store 发布。
💰 8. In-App Purchase / 支付
<key>com.apple.developer.in-app-payments</key><array><string>merchant.com.example.app</string></array>解释:Apple Pay 商户 ID,用于支付。
🔑 9. Keychain 共享
<key>keychain-access-groups</key><array><string>$(AppIdentifierPrefix)com.example.shared</string></array>解释:允许多个应用共享钥匙串数据,常用于同一开发者的多个 App 之间共享登录凭据。
🔗 10. App Groups(应用组)
<key>com.apple.security.application-groups</key><array><string>group.com.example.shared</string></array>解释:让**主 App 与扩展(Extension、Widget)**之间共享数据(通过 UserDefaults、文件系统)。
🌐 11. Associated Domains(关联域名)
<key>com.apple.developer.associated-domains</key><array><string>applinks:example.com</string><string>webcredentials:example.com</string><string>activitycontinuation:example.com</string></array>- applinks:通用链接(Universal Links)
- webcredentials:网站密码自动填充
- activitycontinuation:Handoff 接力
🚗 12. CarPlay
<key>com.apple.developer.carplay-audio</key><true/><key>com.apple.developer.carplay-communication</key><true/>解释:各种 CarPlay 应用类型的授权(音频、通讯、导航等),需向苹果单独申请。
🏥 13. HealthKit / HomeKit
<key>com.apple.developer.healthkit</key><true/><key>com.apple.developer.homekit</key><true/>解释:健康数据 / 家居设备控制。
📶 14. Network Extensions(网络扩展)
<key>com.apple.developer.networking.networkextension</key><array><string>packet-tunnel-provider</string><string>app-proxy-provider</string><string>content-filter-provider</string></array>解释:开发 VPN、防火墙、内容过滤应用时需要,必须向苹果单独申请。
🎮 15. Game Center
<key>com.apple.developer.game-center</key><true/>📞 16. SiriKit
<key>com.apple.developer.siri</key><true/>🔐 17. Sign in with Apple
<key>com.apple.developer.applesignin</key><array><string>Default</string></array>🖨️ 18. Print(打印,macOS 沙盒)
<key>com.apple.security.print</key><true/>⚙️ 19. 特殊/系统级 Entitlements
<key>com.apple.security.cs.allow-jit</key><true/><key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/><key>com.apple.security.cs.disable-library-validation</key><true/><key>com.apple.security.cs.debugger</key><true/>- allow-jit:允许 JIT 编译(如 JavaScriptCore、模拟器)
- allow-unsigned-executable-memory:允许未签名的可执行内存
- disable-library-validation:允许加载非同签名的动态库(插件系统)
- cs.debugger:允许作为调试器附加到其他进程
四、Entitlements 文件的实际操作
1. 在 Xcode 中启用
Target → Signing & Capabilities → + Capability
2. 查看已签名应用的 Entitlements
codesign-d--entitlements:- /path/to/App.app3. 手动签名时指定
codesign--entitlementsMyApp.entitlements--sign"Developer ID"MyApp.app五、Entitlements 的三个关键约束
| 层级 | 说明 |
|---|---|
| Provisioning Profile | 描述文件必须包含对应的 entitlement,否则无法安装 |
| App ID Capabilities | 苹果开发者后台的 App ID 必须开启对应能力 |
| 代码签名 | 签名时嵌入 entitlements,不能后期修改 |
三者必须一致,否则会出现:
Provisioning profile doesn't include entitlementMissing entitlementsCode signing error
六、常见问题排查
- Entitlement 不生效:检查 Provisioning Profile 是否包含
- 签名失败:检查 App ID 是否已启用该能力
- 上架被拒:检查 entitlement 是否需要苹果特批(如 CarPlay、NetworkExtension)
- 企业签 / 重签:重签必须使用支持相同 entitlement 的证书