Make features discoverable with TipKit
System & Services 进阶 20m

用 TipKit 让功能更容易被发现

Make features discoverable with TipKit

2023年6月5日

在 Apple 官方观看视频

一句话判断

TipKit 不只是”弹个提示框”那么简单——它的规则系统(参数规则 + 事件规则)让你能精确控制”谁在什么时候看到什么提示”,这是做用户引导的正确姿势。

这场 Session 讲了什么

TipKit 是 Apple 全新推出的用户教育框架,帮助开发者在 App 中展示功能提示。覆盖 iPhone、iPad、Mac、Apple Watch 和 Apple TV。

Session 分四部分展开:

创建提示:提示由标题和消息组成。标题应该是直接的动作短语,消息包含用户能记住的收益信息或操作指引。支持两种展示方式——Popover(浮层,指向特定 UI 元素,不改变布局)和 Inline(内嵌,App UI 自动让出空间)。tvOS 只支持 Popover。

规则系统(核心亮点):

  • 参数规则(Parameter-based):基于 Swift 值类型做条件判断,适合”用户是否已登录”这类持久状态。
  • 事件规则(Event-based):基于用户行为计数,比如”访问某个页面 3 次后才展示提示”。支持日期范围查询(“过去 5 天内访问 3 次”)和自定义关联类型(“访问同一个页面 3 次”)。

展示控制:管理提示的显示和消除频率,避免教育信息变成垃圾弹窗。TipsCenter 负责持久化提示状态和事件数据。

测试:提供测试工具验证提示逻辑。

Session 明确区分了什么该用 TipKit、什么不该用。正确的场景:教用户新功能、发现隐藏功能、展示更快的方式。错误场景:广告推销、错误消息、“我们改进了某功能”、过于复杂的多步操作指南。

值得深挖的点

**事件规则中的关联类型(Associated Types)**是最强的精准度工具。它让你不只是计数”用户访问了详情页”,而是追踪”用户访问了同一个后院的详情页 3 次”。通过在事件捐赠时附带上下文数据,规则可以基于特定对象做条件匹配。不过 Session 也提醒了:关联数据越大,查询性能越差,要控制数据尺寸。

“先让用户自己发现”的设计哲学贯穿整个 TipKit。Apple 不建议用户第一次打开 App 就被提示轰炸。通过事件规则设置”使用 N 次后再提示”的门槛,给用户有机探索的空间。只有当用户可能错过功能时才介入——这是一个关于教育时机的框架。

参数规则和事件规则的组合可以构建相当精确的受众筛选。比如”已登录 + 过去 5 天内访问同一后院 3 次 + 从未收藏过后院”,这样的规则组合确保只有最可能受益的用户才会看到提示。

代码片段

定义提示和基本规则:

import TipKit

// 定义提示
struct FavoriteBackyardTip: Tip {
    var title: Text {
        Text("收藏你喜欢的后院")
    }
    var message: Text? {
        Text("长按星标按钮即可收藏,快速找到你最关心的后院")
    }
    var image: Image? {
        Image(systemName: "star")  // 用图标关联功能
    }
}

// 参数规则:用户已登录
@Parameter static var isLoggedIn: Bool = false

// 事件:用户访问后院详情页
static var visitedBackyardDetail = Event(id: "visitedBackyardDetail")

// 组合规则
var rules: [Rule] {
    // 规则1:必须已登录
    Rule(Self.$isLoggedIn == true)
    // 规则2:过去5天内访问同一后院详情页至少3次
    Rule(Self.visitedBackyardDetail,
         behavior: CountAtLeast(3),
         behaviorModifiers: [QueryByRange(
             from: Calendar.current.date(byAdding: .day, value: -5, to: Date())!
         )])
}

展示提示和捐赠事件:

// 在视图中展示 Popover 提示
struct BackyardDetailView: View {
    var body: some View {
        VStack {
            // ... 后院内容
        }
        .popoverTip(FavoriteBackyardTip())  // Popover 样式
    }
}

// 在视图出现时捐赠事件
struct BackyardDetailView: View {
    let backyardID: String
    var body: some View {
        VStack { /* ... */ }
            .task {
                // 捐赠带关联类型的事件
                FavoriteBackyardTip.visitedBackyardDetail.donate {
                    $0.backyardID = backyardID
                }
            }
    }
}

最佳实践

  • 提示标题用动词开头,比如”收藏你喜欢的后院”而不是”收藏功能介绍”。
  • 消息控制在一句之内,用户扫一眼就能理解收益。太长的提示在真实使用场景中没人会读。
  • 给用户留出自然探索的空间。至少让用户访问相关页面 2-3 次后再展示提示。
  • 用关联类型做精细匹配时,注意控制数据大小——只存必要的 ID,不要存整个对象。
  • 如果功能有设置项,加一个 action button 直接跳转设置页面,缩短操作路径。
  • 测试时使用 TipsCenter 的调试功能,可以重置提示状态和模拟不同规则条件。

还有什么值得关注

  • TipKit 的持久化由 TipsCenter 自动管理,提示和事件数据在 App 重启后保留。
  • Inline 和 Popover 两种展示方式的选择取决于 UI 布局——如果提示区域有重要内容不能遮挡,用 Inline。
  • tvOS 只支持 Popover,因为电视界面没有可调整的布局空间。
  • 可以在提示中链接到 onboarding 流程或帮助文档,形成完整的教育路径。
  • Session 提到的”不适用场景”列表值得打印出来贴在工位上——用 TipKit 做广告或错误提示是滥用。
WWDC 2023