You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS14 WidgetKit:单个Widget能否配置两个动态Intent?

在iOS14 WidgetKit中实现单个Widget带两个搜索式动态输入项的方案

可行,但不能通过绑定两个独立的IntentConfiguration实现,因为单个Widget只能关联一个自定义Intent类型。正确的做法是将两个输入项整合到同一个CustomIntent中,具体步骤如下:

1. 合并自定义Intent定义

打开Intents.intentdefinition文件,创建一个新的自定义Intent(例如命名为DoubleSelectionIntent),添加两个参数:

  • 第一个参数(如firstSelection):类型选择你自定义的Selections实体,勾选「Supports Search」开启搜索功能
  • 第二个参数(如secondSelection):同样选择Selections实体并开启搜索支持

这样Widget的配置界面会自动生成两个带搜索栏的输入项。

2. 更新IntentHandler实现

在IntentHandler中,为合并后的Intent的两个参数分别实现选项提供方法:

class IntentHandler: INExtension, DoubleSelectionIntentHandling {
    // 为第一个输入项提供搜索选项
    func provideFirstSelectionOptionsCollection(for intent: DoubleSelectionIntent, with completion: @escaping (INObjectCollection<Selections>?, Error?) -> Void) {
        // 构造你的选项数据,这里示例生成几个测试项
        let options = [
            Selections(identifier: "opt1", display: "选项1"),
            Selections(identifier: "opt2", display: "选项2"),
            Selections(identifier: "opt3", display: "选项3")
        ]
        completion(INObjectCollection(items: options), nil)
    }

    // 为第二个输入项提供搜索选项
    func provideSecondSelectionOptionsCollection(for intent: DoubleSelectionIntent, with completion: @escaping (INObjectCollection<Selections>?, Error?) -> Void) {
        let options = [
            Selections(identifier: "optA", display: "选项A"),
            Selections(identifier: "optB", display: "选项B"),
            Selections(identifier: "optC", display: "选项C")
        ]
        completion(INObjectCollection(items: options), nil)
    }

    // 可选:实现确认Intent的方法
    func confirm(intent: DoubleSelectionIntent, completion: @escaping (DoubleSelectionIntentResponse) -> Void) {
        completion(DoubleSelectionIntentResponse(code: .success, userActivity: nil))
    }
}

3. 配置Widget结构体

将Widget的IntentConfiguration绑定到合并后的DoubleSelectionIntent:

struct MyWidget: Widget {
    let kind: String = "MyWidget"

    var body: some WidgetConfiguration {
        IntentConfiguration(
            kind: kind,
            intent: DoubleSelectionIntent.self,
            provider: WidgetTimelineProvider()
        ) { entry in
            MyWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("双选择Widget")
        .description("支持两个搜索式输入项的Widget")
        .supportedFamilies([.systemSmall, .systemMedium])
    }
}

4. 在TimelineProvider中处理双参数

修改IntentTimelineProvider,指定泛型类型为DoubleSelectionIntent,并在方法中获取两个参数的值用于生成Timeline:

struct WidgetTimelineProvider: IntentTimelineProvider {
    typealias Intent = DoubleSelectionIntent
    typealias Entry = WidgetEntry

    func placeholder(in context: Context) -> WidgetEntry {
        WidgetEntry(date: Date(), firstChoice: nil, secondChoice: nil)
    }

    func getSnapshot(for configuration: DoubleSelectionIntent, in context: Context, completion: @escaping (WidgetEntry) -> Void) {
        let entry = WidgetEntry(
            date: Date(),
            firstChoice: configuration.firstSelection,
            secondChoice: configuration.secondSelection
        )
        completion(entry)
    }

    func getTimeline(for configuration: DoubleSelectionIntent, in context: Context, completion: @escaping (Timeline<WidgetEntry>) -> Void) {
        // 根据两个选择的参数获取数据,生成时间线条目
        let currentEntry = WidgetEntry(
            date: Date(),
            firstChoice: configuration.firstSelection,
            secondChoice: configuration.secondSelection
        )
        let timeline = Timeline(entries: [currentEntry], policy: .atEnd)
        completion(timeline)
    }
}

// 对应的TimelineEntry结构体
struct WidgetEntry: TimelineEntry {
    let date: Date
    let firstChoice: Selections?
    let secondChoice: Selections?
}

关键说明

WidgetKit不支持单个Widget绑定多个独立Intent,必须将多个输入项整合到同一个Intent中。通过这种方式,用户在添加Widget时,配置界面会依次显示两个带搜索栏的输入字段,分别对应你定义的两个参数,且各自的搜索选项由IntentHandler中对应的方法提供。

内容的提问来源于stack exchange,提问作者anoo_radha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 19:52:50