Highlight
App Clips 通过已注册的 URL 启动,开发者需要在 apple-app-site-association 文件加入
appclips关联、给 App Clip target 添加appclips:associated domain,并在 SwiftUI 或 UIKit 中处理NSUserActivityTypeBrowsingWeb来把用户带到对应任务。
核心内容
一个人站在 smoothie 摊前,只想点一杯饮料。她轻触 NFC 标签,屏幕底部出现 App Clip card,点 Open 后直接进入点单页,最后用 Apple Pay 完成购买。这里没有安装完整 App 的等待,也没有从首页寻找菜单的过程。触发点里编码的是一个 URL,系统用这个 URL 找到已注册的 App Clip experience,再把 URL 通过 NSUserActivity 交给 App Clip。(00:49)
这场 session 解决的是链接链路。只有 App Clip target 还不够,网站、App Clip、App Store Connect、Safari 页面都要对上同一个 URL 体系。网站用 apple-app-site-association 文件声明哪些 App Clip 可以处理域名;App Clip target 用 associated domains entitlement 接受 appclips: 域;代码读取 NSUserActivityTypeBrowsingWeb 里的 URL;App Store Connect 决定用户看到的卡片;Smart App Banner 把 Safari 页面接到同一个体验。(03:38)
URL 设计是成败点。App Store Connect 的 advanced App Clip experience 采用最具体的前缀匹配,所以一个租车店可以只注册 https://bikesrental.example/rent,让带不同 query string 的车辆链接落到同一张卡片;连锁咖啡店也可以注册通用门店前缀,再为 Cupertino 旗舰店单独注册更具体的 URL。(11:20)
详细内容
建立网站与 App Clip 的关联
(05:04)App Clip 要替网站 URL 呈现内容,系统必须先验证网站和 App Clip 的关系。做法是在服务器根目录的 .well-known 目录下放置 apple-app-site-association 文件,并在根字典里增加 appclips 条目。
{
"appclips": {
"apps": [ "ABCDE12345.example.fruta.Clip" ]
}
}
关键点:
appclips是 apple-app-site-association 根字典中的新条目,可以和webcredentials、applinks等既有条目并存。apps数组放的是 App Clip app identifier,示例中的ABCDE12345.example.fruta.Clip代表团队 ID 加 App Clip bundle identifier。- Xcode 侧还要给 App Clip target 添加 Associated Domains capability,并填入
appclips:your-website-domain。
在 SwiftUI App 生命周期中处理启动 URL
(06:17)配置好 associated domains 后,App Clip 需要读取系统传入的 web browsing activity。SwiftUI app life cycle 可以直接在 WindowGroup 的根视图上挂 onContinueUserActivity。
import SwiftUI
@main
struct AppClip: App {
var body: some Scene {
WindowGroup {
ContentView()
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { userActivity in
guard let incomingURL = userActivity.webpageURL,
let components = NSURLComponents(url: incomingURL,
resolvingAgainstBaseURL: true)
else {
return
}
// Direct to the linked content in your app clip.
}
}
}
}
关键点:
NSUserActivityTypeBrowsingWeb限定这里只处理来自网页 URL 的启动。userActivity.webpageURL是触发 App Clip 的完整 URL,真实业务通常从 path 或 query string 里取任务参数。NSURLComponents让代码能解析 URL,例如 demo 里读取smoothie=BerryBlue后把数据源切到对应饮品。- 用户升级到完整 App 后,同一个链接会打开完整 App,所以完整 App 也要有对应的 Universal Links 处理逻辑。
在 UIKit scene 生命周期中处理同一件事
(06:54)如果 App Clip 使用 UIKit scene-based life cycle,入口在 UISceneDelegate。逻辑和 SwiftUI 相同:确认 activity 类型,拿到 URL,再把用户导向链接内容。
// Handle NSUserActivity in UISceneDelegate.
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func scene(_ scene: UIScene, continue userActivity: NSUserActivity)
{
// Get URL components from the incoming user activity
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL,
let components = NSURLComponents(url: incomingURL,
resolvingAgainstBaseURL: true)
else {
return
}
// Direct to the linked content in your app clip.
}
}
关键点:
scene(_:continue:)是 scene-based App 接收NSUserActivity的入口。activityType检查可以挡掉非网页启动的 activity。incomingURL解析成功后,不应该停在首页,而应该直接打开 URL 对应的菜单、预约、租赁或支付页面。
配置 default 与 advanced App Clip experiences
(08:32)提交包含 App 和 App Clip 的 build 后,App Store Connect 会出现 App Clip 配置区。Default experience 使用卡片图片、副标题和 action verb,Safari Smart App Banner、Messages link bubble 和默认 App Clip card 都会用这组 metadata。
(09:17)如果 App Clip 要从 NFC、QR code、Maps、Siri nearby suggestions 等入口启动,就要配置 advanced App Clip experience。每个 advanced experience 绑定一个 URL,可以设置独立图片、标题、副标题、action verb,也可以关联物理位置。
(11:20)URL 匹配采用最具体的 prefix match。注册短前缀可以覆盖大量同类链接,注册更具体的 URL 可以给特殊门店或特殊任务换一张卡片。即便注册 URL 只作为前缀使用,App Clip 也必须能处理精确等于注册 URL 的启动,因为 Maps 和 Siri nearby suggestions 可能直接用这个 URL 打开。
让 Safari 页面打开 App Clip
(14:35)Safari Smart App Banner 通过 HTML meta tag 接入 App Clip。网页继续保留 app-id,同时增加 App Clip bundle identifier;这样 iOS 14 可以展示 App Clip 入口,旧系统仍能回退到完整 App 的 App Store 链接。
<meta name="apple-itunes-app"
content="app-clip-bundle-id=com.example.fruta.Clip,
app-id=123456789">
关键点:
name="apple-itunes-app"沿用 Smart App Banner 的 meta tag 名称。app-clip-bundle-id指向 App Clip 的 bundle identifier。app-id继续指向完整 App,服务旧系统和完整 App 下载场景。- Safari 展示 banner 前会验证网站和 App Clip 的 domain association。
用 Xcode 和 TestFlight 覆盖真实入口
(07:16)开发阶段可以在 Xcode scheme 的 environment variables 里设置 _XCAppClipURL。运行 App Clip 时,系统会把这个测试 URL 传进去,便于验证 URL 解析和页面跳转。
(21:19)提交到 App Store Connect 后,TestFlight 的 App Clip 区域可以添加 test invocation points。测试者不需要真实 NFC 标签或二维码,也能按配置好的 title 和 URL 打开不同 experience。
核心启发
门店扫码下单 App Clip
- 做什么:为餐厅、咖啡店、饮品摊生成桌牌 QR code 或 NFC tag,打开后直接进入当前门店的点单页。
- 为什么值得做:session 的 Fruta demo 证明 URL 可以携带具体任务参数,App Clip 读取后能直接选中对应商品或门店。
- 怎么开始:注册门店 URL 前缀,在 App Store Connect 配置 advanced experience,在 SwiftUI 的
onContinueUserActivity中解析 query item 并设置当前菜单状态。
设备租赁入口
- 做什么:给自行车、充电宝、储物柜等设备贴上唯一 URL,扫码后进入对应设备的租赁或解锁页。
- 为什么值得做:prefix match 允许只注册租赁前缀,让不同设备 ID 通过 query string 区分,省去为每台设备注册 experience 的维护成本。
- 怎么开始:把设备 ID 放入 URL query string,App Clip 端用
NSURLComponents解析参数,后端按设备 ID 返回状态和可执行动作。
连锁门店的分层卡片
- 做什么:大多数门店使用同一张 App Clip card,旗舰店或活动门店使用定制图片和副标题。
- 为什么值得做:advanced experience 使用最具体的 prefix match,通用前缀和特殊 URL 可以共存。
- 怎么开始:先注册
https://brand.example/store/这类通用前缀,再为重点门店注册更具体 URL,并在 App Store Connect 中配置不同 metadata。
从网站页面接入 App Clip
- 做什么:在可由 App Clip 更快完成的网页上展示 Safari Smart App Banner,例如预约、快速购买、排队取号。
- 为什么值得做:Smart App Banner 可以把网页访问转成 App Clip 打开,同时保留完整 App 的
app-id回退。 - 怎么开始:在网页加入
apple-itunes-appmeta tag,填入app-clip-bundle-id和完整 App 的app-id,再确认 AASA 文件和 associated domains 已部署。
TestFlight 体验矩阵
- 做什么:上线前为每类入口建立测试调用点,覆盖默认体验、NFC/QR 体验、特殊门店体验和 Safari banner 体验。
- 为什么值得做:session 提到 TestFlight 可以添加 App Clip invocation points,测试者能验证不同 URL 对应的 App Clip card 和跳转。
- 怎么开始:把每个关键 URL 写入 TestFlight 的 App Clip 测试入口,要求测试者记录卡片 metadata、打开结果和落地页参数。
关联 Session
- Explore App Clips — 先从整体理解 App Clips 的定位、触发入口和与完整 App 的关系。
- Streamline your App Clip — 继续优化 App Clip 的任务聚焦、交易流程、通知、位置确认和升级路径。
- Design great App Clips — 设计 App Clip card、流程和下载完整 App 的提示文案。
- What’s new in App Store Connect — 了解 App Store Connect 中配置 App Clip experiences 和 TestFlight 测试的相关入口。
- What’s new in Universal Links — 补齐 Universal Links、associated domains 和 AASA 文件的链接基础。
评论
GitHub Issues · utterances