relevancekit

relevancekit

熱門

使用 RelevanceKit 提升小工具在 Apple Watch 上的能见度。适用于:为 watchOS 小工具提供情境相关性讯号、宣告基于时间或位置的相关性、组合多个相关性提供者(relevance providers)、协助系统在 watchOS 26 上于恰当的时机浮现合适的小工具,或处理跨 RelevanceKit/WidgetKit/HealthKit/MapKit 的智慧型叠放(Smart Stack)作用范围分流。

967星標
49分支
更新於 2026/7/31
SKILL.md
唯讀
名稱
relevancekit
描述

使用 RelevanceKit 提升小工具在 Apple Watch 上的能见度。适用于:为 watchOS 小工具提供情境相关性讯号、宣告基于时间或位置的相关性、组合多个相关性提供者(relevance providers)、协助系统在 watchOS 26 上于恰当的时机浮现合适的小工具,或处理跨 RelevanceKit/WidgetKit/HealthKit/MapKit 的智慧型叠放(Smart Stack)作用范围分流。

RelevanceKit

提供装置端的情境线索,以提升小工具在 Apple Watch「智慧型叠放」中的能见度。RelevanceKit 会根据时间、位置、健身状态、睡眠作息或已连线的硬体,告诉系统小工具在何时具有相关性。
适用 Swift 6.3 / watchOS 26+。

Beta 敏感。 在做出强烈的 RelevanceKit 可用性或行为主张之前,请先重新查阅 Apple 官方文件。

请参阅 references/relevancekit-patterns.md 以取得完整相关小工具(relevant-widget)、时间轴提供者(timeline provider)、分组、预览与权限设计模式。

目录

概述

watchOS 使用两种机制来判定小工具在「智慧型叠放」中的相关性:

  1. 时间轴提供者相关性(Timeline provider relevance)——在现有的 AppIntentTimelineProvider 上实作 relevance(),将 RelevantContext 线索附加至时间轴条目(timeline entries)。支援跨平台使用;但仅有 watchOS 会依据此资料采取动作。
  2. 相关小工具(Relevant widget)——搭配 RelevanceEntriesProvider 使用 RelevanceConfiguration,构建完全由相关性线索驱动的小工具。系统会为每个相关的条目建立独立的「智慧型叠放」卡片。仅限 watchOS 26+。

当小工具总是需要显示资料且相关性属于辅助性质时,请选择时间轴提供者。当小工具应该在条件吻合时才出现,或需要同时显示多张卡片时(例如多笔即将到来的行事历行程),请选择相关小工具。

核心类型

类型 模组 角色
RelevantContext RelevanceKit 情境线索(日期、位置、健身、睡眠、硬体)
WidgetRelevance WidgetKit 针对某种小工具类型(kind)的相关性属性集合
WidgetRelevanceAttribute WidgetKit 将小工具设定与 RelevantContext 配对
WidgetRelevanceGroup WidgetKit 控制在「智慧型叠放」中的分组行为
RelevanceConfiguration WidgetKit 由相关性线索驱动的小工具设定 (watchOS 26+)
RelevanceEntriesProvider WidgetKit 为设定了相关性的小工具提供条目 (watchOS 26+)
RelevanceEntry WidgetKit 算绘一张相关小工具卡片所需的数据 (watchOS 26+)

RelevanceConfigurationRelevanceEntriesProviderRelevanceEntry 皆属于 WidgetKit API。只有在它们作为对外公开 RelevanceKit 线索的 watchOS 相关小工具工作流程的一部分时,才保留在本 Skill 的探讨范围内。

设定

导入

import RelevanceKit
import WidgetKit

平台可用性

RelevantContext 虽宣告于多平台(iOS 17+、watchOS 10+),但 RelevanceKit 功能仅在 watchOS 上实际生效。在其他平台上呼叫该 API 不会产生任何效果。时间轴提供者的 relevance() 可用于 iOS 18+、macOS 15+、visionOS 26+ 与 watchOS 11+,方便共用提供者程式码。RelevanceConfigurationRelevanceEntriesProviderRelevanceEntry 仅支援 watchOS 26+。

权限

特定的相关性线索需要取得授权或设定 Target:

线索 所需权限
.location(inferred:) 包含此功能的 App 请求位置存取权限;小工具扩充功能(widget extension)宣告 NSWidgetWantsLocation
.location(_:) (CLRegion) 包含此功能的 App 请求位置存取权限;小工具扩充功能宣告 NSWidgetWantsLocation
.location(category:) 包含此功能的 App 请求位置存取权限;小工具扩充功能宣告 NSWidgetWantsLocation
.fitness(.workoutActive) 取得 HealthKit 对 HKWorkoutType 的存取权限
.fitness(.activityRingsIncomplete) 取得 HealthKit 对 appleExerciseTimeappleMoveTimeappleStandTime 的存取权限
.sleep(_:) HealthKit sleepAnalysis 权限
.hardware(headphones:)
.date(...)

请将位置使用说明字串(location purpose strings)新增至包含此功能的 App 的 Info.plist 中,而不只是小工具扩充功能。在小工具程式码中,依赖位置线索之前请先检查 CLLocationManager.isAuthorizedForWidgetUpdates。至于健身与睡眠线索,请在提供相关性的 App 与小工具扩充功能 Target 中启用 HealthKit 并请求精确的读取类型。

相关性提供者

方案 1:带相关性的时间轴提供者

在现有的 AppIntentTimelineProvider 中新增 relevance() 方法。此方法可在 iOS 与 watchOS 之间共用程式码,同时为 watchOS 的「智慧型叠放」增添智慧判断能力。

struct MyProvider: AppIntentTimelineProvider {
    // ... snapshot, timeline, placeholder ...

    func relevance() async -> WidgetRelevance<MyWidgetIntent> {
        let attributes = events.map { event in
            let context = RelevantContext.date(
                from: event.startDate,
                to: event.endDate
            )
            return WidgetRelevanceAttribute(
                configuration: MyWidgetIntent(event: event),
                context: context
            )
        }
        return WidgetRelevance(attributes)
    }
}

方案 2:RelevanceEntriesProvider (watchOS 26+)

构建一个仅在条件匹配时才出现的小工具。系统会呼叫 relevance() 以了解小工具在何时产生作用,接着呼叫 entry() 并传入相符的设定来取得算绘资料。

@available(watchOS 26.0, *)
struct MyRelevanceProvider: RelevanceEntriesProvider {
    func relevance() async -> WidgetRelevance<MyWidgetIntent> {
        let attributes = events.map { event in
            WidgetRelevanceAttribute(
                configuration: MyWidgetIntent(event: event),
                context: RelevantContext.date(event.date, kind: .scheduled)
            )
        }
        return WidgetRelevance(attributes)
    }

    func entry(
        configuration: MyWidgetIntent,
        context: Context
    ) async throws -> MyRelevanceEntry {
        if context.isPreview {
            return .preview
        }
        return MyRelevanceEntry(event: configuration.event)
    }

    func placeholder(context: Context) -> MyRelevanceEntry {
        .placeholder
    }
}

边界分流

当一项功能混合了小工具、位置、体能训练(workout)与「智慧型叠放」相关性时,请保持 RelevanceKit 专注于 RelevantContextWidgetRelevanceAttribute、提供者的 relevance()RelevantIntentManager、相关小工具接管交接(handoffs)以及相关性线索的权限。将时间轴、重载预算(reload budgets)、尺寸系列(families)、算绘(rendering)、APNs 小工具推送、即时动态(Live Activities)和小工具控制项(Controls)分流至 WidgetKit;将 HKWorkoutSessionHKLiveWorkoutBuilderHKWorkoutRoute、查询、活力能量条/睡眠资料与授权 UX 分流至 HealthKit;并将 MKLocalSearchMKLocalSearchCompleterMKDirections、地理编码、授权、区域、地理围栏与地点资料分流至 MapKit/CoreLocation。

基于时间的相关性

时间线索用于告知系统:小工具在某个特定时刻或其前后具有重要性。

单一日期

RelevantContext.date(eventDate)

带有 Kind 的日期

DateKind 提供了关于时间相关性性质的额外提示:

Kind 用途
.default 一般时间相关性
.scheduled 已排定的行程(会议、航班)
.informational 在某时间点附近具有相关性的资讯(天气预报)
RelevantContext.date(meetingStart, kind: .scheduled)

日期范围

// 使用 from/to
RelevantContext.date(from: startDate, to: endDate)

// 使用 DateInterval
RelevantContext.date(interval: dateInterval, kind: .scheduled)

// 使用 ClosedRange
RelevantContext.date(range: startDate...endDate, kind: .default)

基于位置的相关性

推断位置

系统会从使用者的日常作息中推断特定位置。无需坐标。

RelevantContext.location(inferred: .home)
RelevantContext.location(inferred: .work)
RelevantContext.location(inferred: .school)
RelevantContext.location(inferred: .commute)

在返回线索前,请套用权限表格中的位置相关设定,并检查 CLLocationManager.isAuthorizedForWidgetUpdates

特定区域

import CoreLocation

let region = CLCircularRegion(
    center: CLLocationCoordinate2D(latitude: 37.3349, longitude: -122.0090),
    radius: 500,
    identifier: "apple-park"
)
RelevantContext.location(region)

兴趣点类别 (26.0+ SDK)

指明在特定类别的任何地点附近具有相关性。若类别不支援则返回 nil。此建构函式在 Apple 平台 26.0+ 的 SDK 中均可用,但 RelevanceKit 线索仍仅影响 watchOS 上的「智慧型叠放」行为。

import MapKit

if let context = RelevantContext.location(category: .beach) {
    // 当使用者靠近海滩时,小工具即具备相关性
}

健身与睡眠相关性

健身

// 当活动记录环未完成时具备相关性
RelevantContext.fitness(.activityRingsIncomplete)

// 在进行体能训练期间具备相关性
RelevantContext.fitness(.workoutActive)

请套用权限章节中准确的健身对应设定。

睡眠

// 在就寝时间前后具备相关性
RelevantContext.sleep(.bedtime)

// 在起床时间前后具备相关性
RelevantContext.sleep(.wakeup)

请套用权限章节中的睡眠对应设定。

硬体相关性

// 当连线至耳机时具备相关性
RelevantContext.hardware(headphones: .connected)

无需特殊权限。

组合讯号

WidgetRelevance 阵列中返回多个 WidgetRelevanceAttribute 值,即可让小工具在多种不同条件下皆具备相关性。

func relevance() async -> WidgetRelevance<MyIntent> {
    var attributes: [WidgetRelevanceAttribute<MyIntent>] = []

    // 早上通勤期间具备相关性
    attributes.append(
        WidgetRelevanceAttribute(
            configuration: MyIntent(mode: .commute),
            context: .location(inferred: .commute)
        )
    )

    // 在工作地点具备相关性
    attributes.append(
        WidgetRelevanceAttribute(
            configuration: MyIntent(mode: .work),
            context: .location(inferred: .work)
        )
    )

    // 在排定行程前后具备相关性
    for event in upcomingEvents {
        attributes.append(
            WidgetRelevanceAttribute(
                configuration: MyIntent(eventID: event.id),
                context: .date(event.date, kind: .scheduled)
            )
        )
    }

    return WidgetRelevance(attributes)
}

顺序很重要。 请依优先顺序排列返回的相关性属性。系统可能仅会使用所提供相关性的其中一部分。

小工具整合

搭配 RelevanceConfiguration 的相关小工具

@available(watchOS 26, *)
struct MyRelevantWidget: Widget {
    var body: some WidgetConfiguration {
        RelevanceConfiguration(
            kind: "com.example.relevant-events",
            provider: MyRelevanceProvider()
        ) { entry in
            EventWidgetView(entry: entry)
        }
        .configurationDisplayName("Events")
        .description("Shows upcoming events when relevant")
    }
}

与时间轴小工具关联

当时间轴小工具与相关小工具皆显示相同资料时,请使用 associatedKind 来防止重复的卡片。系统会替换...

<!-- truncated for translation batch; full body continues in source -->