Highlight
Session 由 Charles Ying 主讲,围绕四个新特性展开:App Clips 体积限制从 10MB 提升到 15MB(需 iOS 16);新增 App Clip Diagnostics 诊断工具,帮助排查 Universal Link 配置问题;App Clips 现在可以读取 CloudKit 公共数据库;以及 Keychain 数据在用户安装完整 App 时自动迁移。
核心内容
App Clip 的目标很明确:用户在餐厅、停车场、网页或 Messages 里遇到一个任务,马上完成,不先安装完整 App。
这个目标让开发者一直受两个约束影响。第一,体积必须小。过去的 10MB 上限会逼你删除资源、拆分功能、推迟加载内容。第二,体验必须接近完整 App。支付、登录、读取菜单、展示地点信息,这些流程都需要数据和安全存储。
WWDC 2022 的更新就是把这两个方向往前推了一步。iOS 16 把 App Clip 的体积上限提高到 15MB;App Clip Diagnostics 帮你检查 URL、实体码、Safari、iMessage 和 Universal Link 配置;CloudKit 公共数据库可以直接读取;Keychain 项会在用户安装完整 App 后迁移。
最后一块是运营问题。高级 App Clip 体验一多,手动在 App Store Connect 里创建地点、图片和本地化信息会变成重复劳动。App Store Connect 的 App Clip experiences Web API 把这部分变成可脚本化流程。
详细内容
15MB 上限:先决定最低系统版本
(01:07)App Clips 新增 15MB 上限,条件是 App Clip 的最低系统版本设为 iOS 16。如果还要兼容 iOS 15 或更早系统,仍然要保持在 10MB 内。
这个变化给复杂一点的即时任务留下了空间。比如点餐 App Clip 可以保留更多 UI 资源、支付流程和状态页。但 Charles Ying 也强调,速度仍然是 App Clip 的核心。用户不一定处在高速网络环境里,启动后再下载额外资源可以减轻初始下载负担。
概念决策:App Clip 体积目标
1. 如果 App Clip 的最低版本是 iOS 16:压缩后下载大小可以接近 15MB。
2. 如果要支持 iOS 15 或更早版本:压缩后下载大小仍需控制在 10MB 内。
3. 启动后才需要的大资源:放到启动后按需获取。
关键点:
- 15MB 上限只适用于最低版本为 iOS 16 的 App Clip。
- 10MB 仍是兼容 iOS 15 及更早系统时的边界。
- 启动后再下载额外资源是演讲中明确提到的补充策略,具体下载机制需要按 App 自身架构选择。
- 体积放宽不等于可以忽略启动速度,App Clip 仍面向即时场景。
App Clip Diagnostics:把 URL 配置问题直接指出来
(02:10)App Clip 的入口很多:实体 App Clip Code、Safari、iMessage、Universal Link。问题也经常出在这些配置之间。Safari 横幅不出现,或者用户点了链接却打开网页,都可能是 Associated Domains、体验配置或 URL 匹配出了问题。
iOS 16 的 App Clip Diagnostics 放在设备的 Developer Settings 里。连接 Xcode 后开启开发者设置,进入 App Clips Testing 的 Diagnostics,输入 URL,系统会检查配置。如果通过,会看到绿色勾选;如果失败,界面会说明具体问题,并给出文档链接。
概念流程:使用 App Clip Diagnostics
1. 将 iPhone 或 iPad 连接到 Xcode,开启 Developer Settings。
2. 打开 Developer Settings > App Clips Testing > Diagnostics。
3. 输入要测试的 App Clip URL。
4. 查看 App Clip experience、Safari、iMessage 和 Universal Link 配置检查结果。
5. 根据失败项链接到的文档修正配置。
关键点:
- Diagnostics 是设备上的开发者工具,不需要你在 App 中集成新代码。
- 它会检查使用实体码的 App Clip experiences,也会检查 Safari 和 iMessage。
- 它还会检查 Universal Link 的 Associated Domains 配置。
- 失败结果会说明具体配置步骤,适合排查“打开了网页而不是 App Clip”这类问题。
CloudKit:App Clip 可以读取公共数据库
(03:27)过去 App Clip 不能使用 CloudKit。如果 App Clip 要读取菜单、商品或地点资源,常见做法是接自己的服务器。
iOS 16 开始,App Clips 可以读取 CloudKit public database。这样完整 App 和 App Clip 可以共用同一个 CloudKit container 和同一套读取代码。边界也很清楚:App Clip 只能读公共数据库,不能写入 CloudKit;也不能使用 cloud documents 和 key-value store。
// Read your CloudKit public database from your App Clip
let container = CKContainer.default()
let publicDatabase = container.publicCloudDatabase
let record = try await publicDatabase.record(for:
CKRecord.ID(recordName: "A928D582-9BB6-E9C5-7881-E4EAF615E0CD"))
if let title = record["Title"] as? String,
let description = record["Description"] as? String {
print("Fetched a food item from CloudKit: \(title) \(description)")
}
关键点:
CKContainer.default()取得 App Clip 使用的 CloudKit container。container.publicCloudDatabase明确访问公共数据库,这是 App Clip 支持的范围。record(for:)用CKRecord.ID拉取指定记录。record["Title"]和record["Description"]读取字段后转成字符串。- 这段代码只读取数据,符合演讲中“App Clips can read from a public database but can’t write data to CloudKit”的限制。
启用方式也在演讲中给出:打开 App Clip target 的 Signing and Capabilities,选择要使用的 CloudKit container。这个 container 可以是新建的,也可以和完整 App 共用。
Keychain 迁移:敏感数据不用先放 App Group
(04:59)登录 token、支付信息这类数据适合放在 Keychain。过去 App Clip 升级到完整 App 时,开发者常用 shared app group container 做中转:App Clip 写入共享容器,完整 App 安装后读取,再放进 Keychain。
iOS 16 改掉了这段绕路。用户安装完整 App 后,App Clip Keychain 里的 items 会转移到完整 App。App Clip 可以直接把安全数据写进 Keychain,完整 App 用同样的 Keychain 查询代码读取。
// Write authentication token to App Clip keychain
let addSecretsQuery: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecValueData as String: "smoothie-secret".data(using: .utf8),
kSecAttrLabel as String: "foodsample-appclip"
]
SecItemAdd(addSecretsQuery as CFDictionary, nil)
// Read authentication token from app or App Clip
var readSecretsQuery: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecReturnAttributes as String: true,
kSecAttrLabel as String: "foodsample-appclip",
kSecReturnData as String: true
]
var secretsCopy: AnyObject?
SecItemCopyMatching(readSecretsQuery as CFDictionary, &secretsCopy)
关键点:
kSecClassGenericPassword表示这里存的是通用密码类 Keychain item。kSecValueData保存 token 数据,示例里是smoothie-secret的 UTF-8 数据。kSecAttrLabel给 item 加标签,方便完整 App 识别它来自 App Clip。SecItemAdd在 App Clip 中写入 Keychain。SecItemCopyMatching用同样标签读取 item,App 和 App Clip 都可以使用这段查询代码。
这里也有边界:shared keychain groups 和 iCloud Keychain 不支持。这样仍然能保持 App Clip 的承诺:当 App Clip 不再使用时,iOS 会删除 App Clip 和它的数据。
App Clip Experiences API:自动创建高级体验
(06:28)高级 App Clip 体验会绑定信息或地点。餐厅、门店、停车点越多,手工维护就越难。App Store Connect 提供的 App Clip experiences Web API 用来自动化创建和更新这些体验。
演讲里的流程分三步:先通过 App item ID 和 App Clip bundle ID 取得 App Clip resource ID;再上传 header image;最后用 App Clip resource ID 和 header image ID 创建高级 App Clip 体验。
# Get the App Clip resource ID
GET /v1/apps/1234567890/appClips?filter[bundleId]=com.example.foodsample.Clip
# Response
{
"data": {
"attributes": {
"bundleId": "com.example.foodsample.Clip"
},
"id": "726ad1bb-3e1b-40eb-a986-d8a9897e4f1e"
}
}
关键点:
GET /v1/apps/{appId}/appClips用 App 的 item ID 定位 App。filter[bundleId]用 App Clip bundle ID 缩小范围。- 响应里的
data.id是 App Clip resource ID,后续创建体验时要放进 relationship。 - 示例中的 ID 是演讲给出的示例资源 ID,不应直接复制到真实请求中。
上传 header image 是第二步。
# Upload a header image for the advanced App Clip experience
POST /v1/appClipAdvancedExperienceImages
{
"data": {
"type": "appClipAdvancedExperienceImages",
"attributes": {
"fileName": "Hero_image_US.png",
"fileSize": 43500
}
}
}
# Response
{
"data": {
"attributes": "...",
"id": "91c52741-832b-48a2-8935-1797655edbe7"
}
}
关键点:
POST /v1/appClipAdvancedExperienceImages创建高级体验使用的图片资源。fileName和fileSize描述要上传的图片文件。- 响应里的
data.id是 header image resource ID。 - 这个 ID 会在创建高级体验的
headerImagerelationship 中使用。
第三步创建高级 App Clip 体验。
# Create advanced App Clip experience
POST /v1/appClipAdvancedExperiences
{
"data": {
"type": "appClipAdvancedExperiences",
"attributes": {
"action": "OPEN",
"businessCategory": "FOOD_AND_DRINK",
"defaultLanguage": "EN",
"isPoweredBy": true,
"link": "https://fruta.example.com/restauraunt/simply_salad",
"place": {
"names": [ "Caffe Macs" ],
"mapAction": "RESTAURANT_ORDER_FOOD",
"displayPoint": {
"coordinates": { "latitude": 37.33611, "longitude": -122.00731 },
"source": "CALCULATED"
}
}
},
"relationships": {
"appClip": {
"data": {
"type": "appClip",
"id": "726ad1bb-3e1b-40eb-a986-d8a9897e4f1e"
}
},
"headerImage": {
"data": {
"type": "appClipAdvancedExperienceImages",
"id": "91c52741-832b-48a2-8935-1797655edbe7"
}
}
},
"included": {
"type": "appClipAdvancedExperienceLocalizations",
"attributes": {
"language": "EN",
"subtitle": "Fresh salad every day",
"title": "Simply Salad"
}
}
}
}
关键点:
attributes.action、businessCategory、defaultLanguage和link描述体验本身。place用于绑定 Maps 地点,包含地点名、地图动作和坐标。relationships.appClip关联第一步拿到的 App Clip resource ID。relationships.headerImage关联第二步创建的 header image resource ID。included放本地化标题和副标题,示例里是英文的Simply Salad和Fresh salad every day。
核心启发
-
做一个 CloudKit 驱动的轻量菜单 App Clip:把菜单、商品或门店展示数据放在 CloudKit 公共数据库。为什么值得做:App Clip 可以和完整 App 共用读取逻辑,不必为了只读数据单独维护一套服务端接口。怎么开始:在 App Clip target 的 Signing and Capabilities 中选择 CloudKit container,用
CKContainer.default().publicCloudDatabase读取公共记录。 -
把 App Clip 登录 token 直接写入 Keychain:用户用 App Clip 完成登录或支付授权后,把短期 token 存为 Keychain item。为什么值得做:用户安装完整 App 后,Keychain item 会迁移过去,完整 App 可以延续状态。怎么开始:用
SecItemAdd写入带kSecAttrLabel的 item,在完整 App 中用SecItemCopyMatching查询同一标签。 -
为每次上线增加 URL 诊断清单:发布前在真机 Developer Settings 中对关键 App Clip URL 跑 App Clip Diagnostics。为什么值得做:它能直接指出 Safari 横幅、iMessage、实体体验和 Universal Link 配置问题。怎么开始:连接 Xcode 开启 Developer Settings,输入每类入口的 URL,把失败项作为发布阻断条件。
-
用脚本批量创建门店 App Clip 体验:餐饮、停车、预约类 App 可以把门店数据转成 App Store Connect API 请求。为什么值得做:高级 App Clip 体验通常和地点、图片、本地化标题绑定,数量增长后手动维护容易出错。怎么开始:先调用
GET /v1/apps/{appId}/appClips获取 App Clip resource ID,再上传 header image,最后调用POST /v1/appClipAdvancedExperiences创建体验。 -
重新评估 App Clip 的最低版本策略:如果产品需要更多资源,可以考虑把 App Clip 最低版本设为 iOS 16。为什么值得做:15MB 上限能容纳更完整的即时流程。怎么开始:先用 Xcode 的体积报告确认压缩后大小,再决定是保持 iOS 15 兼容,还是用 iOS 16 换取 15MB 空间。
关联 Session
- What’s new in App Clips — 补充 iOS 15 中 App Clips 的发现、回访和测试流程更新,适合放在 2022 更新前阅读。
- Explore App Clips — App Clips 的入门全景,解释触发入口、生命周期和基础开发模型。
- Streamline your App Clip — 讲解体积、启动速度和资源拆分,直接对应本 session 中 15MB 上限和速度提醒。
- Create App Clips for other businesses — 讲平台型 App 如何为商户创建 App Clips,和高级体验批量管理场景相关。
- Expanding automation with the App Store Connect API — App Store Connect API 自动化的基础背景,可帮助理解 App Clip Experiences API 的工作流。
评论
GitHub Issues · utterances