WWDC Quick Look 💓 By SwiftGGTeam
Configure and link your App Clips

Configure and link your App Clips

观看原视频

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 根字典中的新条目,可以和 webcredentialsapplinks 等既有条目并存。
  • 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-app meta 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

评论

GitHub Issues · utterances