Explore App Clips
System & Services 入门 30m

深入了解 App Clips

Explore App Clips

2020年6月22日

在 Apple 官方观看视频

一句话判断

App Clips 是 iOS 14 最重要的新范式——它不只是”小应用”,而是重新定义了用户与物理世界交互的方式。这场 Session 是理解 App Clips 全貌的最佳入口。

这场 Session 讲了什么

这是一场全景式的 App Clips 入门介绍。App Clips 是主应用的轻量级版本,体积限制在 10MB,用户无需安装完整应用即可通过 NFC 标签、QR 码、Safari App Clip 横幅、Messages 链接和 Apple Maps 地点卡片触发使用。Session 全面覆盖了 App Clips 的技术架构、触发方式、生命周期和开发流程。

App Clips 的核心理念是”即时体验”。用户在真实世界中遇到一个 App Clip 的触发点(比如餐厅桌上的 QR 码、停车场缴费桩上的 NFC 标签),用 iPhone 靠近或扫码,几秒内就能启动对应功能。系统会自动处理下载、启动和清理——用户不需要关心”安装”这个概念。

Session 详细介绍了 App Clips 的六种触发方式:NFC 标签、视觉码(QR 码 + App Clip Code)、Safari App Clip 横幅、Messages 中的链接、Apple Maps 地点卡片、以及 Nearby Suggestions(附近建议)。每种触发方式都对应不同的用户场景——NFC 适合固定场所,QR 码适合印刷品,Safari 横幅适合网站引流。

技术架构方面,App Clip 是主应用 target 的兄弟 target,共享代码和资源。通过 Xcode 的新模板可以快速创建 App Clip target,它会自动配置必要的 entitlements 和 associated domains。

值得深挖的点

App Clip 的生命周期管理

App Clip 的生命周期完全由系统管理。用户触发后,系统下载 App Clip(如果尚未缓存)、启动它、传递 URL 参数。用户完成操作后,App Clip 进入后台,一段时间后被系统自动清理。如果用户安装了完整应用,App Clip 的数据和状态会自动迁移过去。这个”来无影去无踪”的体验是 App Clips 区别于传统应用的核心特征。

URL 参数驱动的深度链接

每个 App Clip 体验都由一个 URL 定义。当用户通过 NFC 或 QR 码触发 App Clip 时,完整的 URL(包括查询参数)会传递给应用。你的代码解析这个 URL,直接跳转到对应功能。比如 https://example.com/coffee/order?store=123 会直接打开店铺 123 的点单页面。这种 URL 驱动的设计让一个 App Clip 可以承载无数种使用场景。

代码片段

// App Clip 的入口配置
import SwiftUI

@main
struct CoffeeApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onContinueUserActivity(
                    NSUserActivityTypeBrowsingWeb
                ) { activity in
                    // 处理 App Clip 的 URL 触发
                    handleIncomingURL(activity)
                }
        }
    }
    
    func handleIncomingURL(_ activity: NSUserActivity) {
        guard let url = activity.webpageURL else { return }
        
        // 解析 URL 路径
        let components = URLComponents(url: url, resolvingAgainstBaseURL: true)
        let path = components?.path ?? ""
        
        switch path {
        case "/order":
            // 直接跳转到点单页面
            let storeId = components?.queryItems?
                .first(where: { $0.name == "store" })?.value
            NotificationCenter.default.post(
                name: .showOrderView,
                object: nil,
                userInfo: ["storeId": storeId ?? ""]
            )
        case "/pay":
            // 直接跳转到支付页面
            let parkingId = components?.queryItems?
                .first(where: { $0.name == "parking" })?.value
            NotificationCenter.default.post(
                name: .showPaymentView,
                object: nil,
                userInfo: ["parkingId": parkingId ?? ""]
            )
        default:
            break
        }
    }
}
// 配置 App Clip 的 Associated Domains
/*
 在 Xcode 中配置:
 1. 打开 App Clip target 的 Signing & Capabilities
 2. 添加 Associated Domains
 3. 添加: appclips:example.com
 
 在服务器上配置 apple-app-site-association:
 {
     "appclips": {
         "apps": ["TEAMID.com.example.CoffeeApp.Clip"]
     }
 }
 
 完整的 AASA 文件路径:
 https://example.com/.well-known/apple-app-site-association
 */
// 处理 App Clip 与完整应用的数据共享
import SharedFramework  // 共享代码框架

class AppClipDataMigrator {
    // 检测是否从 App Clip 迁移到完整应用
    func migrateDataIfNeeded() {
        // 使用 shared UserDefaults 在 App Clip 和完整应用之间传递数据
        let sharedDefaults = UserDefaults(suiteName: "group.com.example.coffee")
        
        if let pendingOrder = sharedDefaults?.object(forKey: "pendingOrder") as? [String: Any] {
            // 将 App Clip 中的未完成订单迁移到完整应用
            OrderManager.shared.restoreOrder(from: pendingOrder)
            sharedDefaults?.removeObject(forKey: "pendingOrder")
        }
    }
    
    // 在 App Clip 中保存临时数据
    func saveTemporaryData(_ order: Order) {
        let sharedDefaults = UserDefaults(suiteName: "group.com.example.coffee")
        sharedDefaults?.set(order.toDictionary(), forKey: "pendingOrder")
    }
}

最佳实践

  • 为每个物理触点(NFC 标签、QR 码)设计独立的 URL 和对应的 App Clip 体验
  • 使用 App Group container 在 App Clip 和完整应用之间共享关键数据
  • App Clip 的启动时间目标:从触发到可交互不超过 3 秒
  • 利用 Sign in with Apple 的静默模式和 Apple Pay 实现零输入的完整交易流程
  • 在 Xcode 中使用 App Clip 体验调试工具模拟各种触发场景

还有什么值得关注

  • App Clip Code 是 Apple 设计的新视觉码,同时包含 NFC 和视觉扫描两种触发方式
  • Nearby Suggestions 功能让用户在靠近 App Clip 触发点时自动收到建议,无需主动扫描
  • App Clip 的缓存策略由系统控制,开发者无法强制保留——重要数据必须持久化到服务器
  • 如果用户通过 App Clip 安装了完整应用,App Store 会标记这次安装的来源
WWDC 2020