为小组件添加智能推荐
Add intelligence to your widgets
2021年6月9日
一句话判断
WidgetKit 在 iOS 15 拿到了「智能推荐」的入场券——你的 Widget 可以被 Siri 建议自动展示在主屏上,但这需要你正确配置 Intent 和 Donation。
这场 Session 讲了什么
iOS 15 中的 Widget 获得了一个重要的新分发渠道:Siri 智能建议。当系统判断用户可能需要你的 Widget 时,会自动在主屏的 Smart Stack 中展示它。这个机制依赖 INRelevantShortcutStore 和 Intent 的 Donation。
Session 讲解了如何让你的 Widget 「可被推荐」。你需要做三件事:创建一个可配置的 Widget(使用 IntentConfiguration),在 app 中 Donate 相关的 INIntent,然后让系统在合适的时间展示你的 Widget。
典型场景:用户每天早上 7 点用你的 app 查看日程。系统学习到这个模式后,会在早上 7 点自动把你的日程 Widget 放到 Smart Stack 的顶部。用户只需要在主屏上滑动就能看到今天的日程。
另外还介绍了 Widget 的「 Reyes 」(Relevance)优化。你可以通过 RelevantShortcutManager 告诉系统你的 Widget 在什么场景下最有用(比如某个地点、某个时间段),系统会据此决定是否展示。
值得深挖的点
Intent Donation 的最佳时机
Intent Donation 不是越多越好。如果你在用户每次点击按钮时都 Donate 一个 Intent,系统会被大量信号淹没,反而无法学到有效的模式。Session 建议:只在用户完成了一个「完整的动作」后才 Donate。比如用户查看了某个城市的天气,Donate 一个「查看天气」的 Intent 并附带城市参数。
Smart Stack 的排序逻辑
Smart Stack 的排序由系统自动完成,开发者无法控制。但你可以通过设置 INRelevantShortcut 的 relevanceScore 来影响排序。score 越高,Widget 被展示的概率越大。建议根据用户的使用频率和最近使用时间来计算 score。
代码片段
// 配置可被 Siri 推荐的 Widget
import WidgetKit
import Intents
// 定义 Widget 的配置 Intent
class CityConfigurationIntent: INIntent {
@NSManaged var city: String?
}
// 在 TimelineProvider 中使用 Intent
struct WeatherIntentProvider: IntentTimelineProvider {
func placeholder(in context: Context) -> WeatherEntry {
WeatherEntry(date: Date(), city: "北京", temperature: 22)
}
func getSnapshot(for configuration: CityConfigurationIntent,
in context: Context,
completion: @escaping (WeatherEntry) -> Void) {
let city = configuration.city ?? "北京"
completion(WeatherEntry(date: Date(), city: city, temperature: 22))
}
func getTimeline(for configuration: CityConfigurationIntent,
in context: Context,
completion: @escaping (Timeline<WeatherEntry>) -> Void) {
let city = configuration.city ?? "北京"
// 根据城市获取天气数据并生成时间线
let entries = generateEntries(for: city)
completion(Timeline(entries: entries, policy: .atEnd))
}
}
// 在 app 中 Donate Intent
import Intents
func donateViewWeatherIntent(city: String) {
let intent = ViewWeatherIntent()
intent.city = city
intent.suggestedInvocationPhrase = "查看\(city)天气"
let interaction = INInteraction(intent: intent, response: nil)
interaction.donate { error in
if let error = error {
print("Donate 失败: \(error)")
}
}
}
// 设置相关快捷方式,提升推荐概率
import Intents
func updateRelevantShortcuts() {
var shortcuts: [INRelevantShortcut] = []
// 为常用城市创建相关快捷方式
let cities = ["北京", "上海", "深圳"]
for city in cities {
let intent = ViewWeatherIntent()
intent.city = city
let shortcut = INShortcut(intent: intent)
let relevantShortcut = INRelevantShortcut(shortcut: shortcut)
// 设置相关度评分
relevantShortcut.shortcutRole = .information
// 设置场景:每天早上推荐
let morningDate = Calendar.current.date(bySettingHour: 7, minute: 0, second: 0, of: Date())!
relevantShortcut.relevanceProviders = [
INDateRelevanceProvider(start: morningDate, end: morningDate.addingTimeInterval(3600))
]
shortcuts.append(relevantShortcut)
}
INRelevantShortcutStore.default.setRelevantShortcuts(shortcuts) { error in
if let error = error {
print("更新相关快捷方式失败: \(error)")
}
}
}
最佳实践
不要为了获得更多推荐而频繁 Donate Intent。系统的智能推荐模型会过滤掉过于频繁的 Donation。一天 Donate 2-3 次比一天 Donate 50 次效果好得多。
为你的 Widget 配置 suggestedInvocationPhrase,这会让用户在用 Siri 语音控制时更容易触发你的 Widget。短语应该自然且简短,比如「查看天气」比「打开天气应用查看当前城市的天气预报」好得多。
还有什么值得关注
INRelevantShortcutStore支持INLocationRelevanceProvider,可以根据用户的位置触发推荐。- Widget 的 Smart Stack 推荐在 iPadOS 15 上也可用。
- 用户可以手动将 Widget 添加到 Smart Stack 中,系统会学习用户的偏好来优化排序。