ConfigurationAppIntent 是一个用于在 iOS 小组件(Widget)中提供自定义配置的工具,属于 App Intents(应用意图)的一部分。它的核心作用是让用户能够通过系统提供的设置界面对小组件进行个性化定制,比如设置显示内容的某些参数。
ConfigurationAppIntent 的作用
1、显示的表情符号
2、小组件的主题颜色
3、显示内容的格式
而这些配置参数会影响小组件的内容和外观。

举个例子:
假设设计一个天气小组件,用户可能想要设置显示的单位(如摄氏度或华氏度)。如果没有这种配置意图,用户只能看到固定的内容,无法自由调整显示内容。而 ConfigurationAppIntent 提供这样一个参数,让用户可以选择自己偏好的单位(摄氏度或华氏度)。

为什么需要提供自定义的参数?
在传统的小组件中(例如早期的 WidgetKit),小组件的内容通常是固定的,或者通过固定的数据源来展示(比如显示当前的天气,或者某个应用的状态)。这种方式虽然简单,但缺乏灵活性,不能让用户在小组件中根据个人需求进行调整。
ConfigurationAppIntent 使得小组件能够变得更加灵活,允许用户根据自己的需求进行个性化配置。它可以通过以下几种方式提升用户体验:
提升自定义程度:用户可以配置小组件显示的数据或外观,而不仅仅是静态的内容。
简化设置过程:开发者通过系统的设置界面提供参数,用户无需手动修改配置文件或设置,而只需要通过图形界面进行选择。
增强交互性:通过用户的自定义配置,小组件可以更加贴合用户的使用习惯和偏好。
小组件设置界面
在 iOS 系统中,当添加一个小组件到主屏幕时,用户通常可以点击小组件进行配置(例如选择显示内容或切换不同的视图)。这些配置项通常是通过 ConfigurationAppIntent 提供的。

通过这种方式,用户可以定制自己的小组件,增强了灵活性和可操作性。
ConfigurationAppIntent的实际应用
struct ConfigurationAppIntent: WidgetConfigurationIntent {
static var title: LocalizedStringResource = "Configuration"
static var description = IntentDescription("This is an example widget.")
// An example configurable parameter.
@Parameter(title: "摄氏度", default: false)
var temperature: Bool
}
WidgetConfigurationIntent 中的 title 和 description 主要是用于开发者理解和定义意图(Intent)的元数据,它们不会直接显示在小组件的用户界面中。它们的作用更多是帮助系统和其他开发者理解这个 Intent 的用途和功能。
@Parameter 是一种属性包装器,用于声明可以由用户配置的参数。它告诉系统这个属性是可以由用户在小组件配置界面中编辑的,类似于通过 App 设置中的界面来进行调整。
@Parameter 的主要作用是将属性标记为可配置的,用户可以在 Widget 配置中修改这些值。
title 是显示给用户的字段名称。
default 是该字段的默认值。如果用户没有提供自定义值,将使用该默认值。

在这个例子中,temperature 是一个可以由用户编辑的字段,默认值为false。用户可以在配置界面中切换这个变量。
在BankletWidgetEntryView文件中,通过entry.configuration. temperature显示ConfigurationAppIntent 配置的参数。
struct BankletWidgetTestView : View {
var entry: Provider.Entry
var body: some View {
VStack {
Text("\(entry.configuration.temperature)")
.font(.title)
.padding()
}
}
}

小组件的编辑状态下,点击小组件后,显示小组件的ConfigurationAppIntent配置的参数,通过编辑配置参数,显示小组件内容的变换。
小组件的编辑界面
在实际的使用中,可以发现小组件的配置界面并不总是统一的格式,不同的小组件可能展示不同的可编辑界面,取决于小组件的类型、功能以及开发者如何设置它们。
1、无法点击编辑的小组件
一些小组件是不可配置的,它们展示的是固定的内容,并不允许用户在主屏幕上通过点击进行编辑。例如,显示时间、天气、股票价格等这些信息的小组件,通常是静态的,只展示数据,不提供配置选项。这些小组件通常具有以下特点:
没有配置意图:开发者没有通过 ConfigurationAppIntent 提供任何可供用户配置的参数。
不支持反转:这类小组件无法通过点击进入配置界面,因为它们没有配置界面可供交互。
内容动态更新:这类小组件的内容通常由应用程序提供的数据源(例如当前时间、天气API等)动态更新。
可以完全移除 ConfigurationAppIntent,改为使用 StaticConfiguration。通过这种方式,Widget 不会显示任何配置界面,且不需要用户进行任何设置。
首先创建一个不依赖于ConfigurationAppIntent的Provider和ProviderEntry:
struct SimpleProviderEntry: TimelineEntry {
let date: Date
}
// 不需要配置的小组件
struct SimpleProvider: TimelineProvider {
func placeholder(in context: Context) -> SimpleProviderEntry {
SimpleProviderEntry(date: Date())
}
func getSnapshot(in context: Context, completion: @escaping (SimpleProviderEntry) -> ()) {
let entry = SimpleProviderEntry(date: Date())
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<SimpleProviderEntry>) -> ()) {
let entry = SimpleProviderEntry(date: Date())
let timeline = Timeline(entries: [entry], policy: .atEnd)
completion(timeline)
}
}
在定义View和Widget时,都需要设置为SimpleProvider:
struct BankletWidgetTestView : View {
var entry: SimpleProvider.Entry
var body: some View {
VStack {
Text("方君宇")
.font(.title)
}
}
}
struct BankletWidgetTest: Widget {
let kind: String = "BankletWidgetTest"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: SimpleProvider()) { entry in
BankletWidgetTestView(entry: entry)
.containerBackground(.secondary, for: .widget)
}
.supportedFamilies([.systemSmall]) // 支持小尺寸
.configurationDisplayName("测试组件名称") // 小组件的显示名称
.description("测试组件描述.") // 小组件的描述
}
}
通过上述配置,可以实现无法点击编辑的小组件。

如果在运行上面的代码报错时,可能是因为涉及Provider的代码没有全部整改过来导致的,View和Widget中都有涉及Provider的代码,全部需要替换完成。
2、@Parameter数据类型
另一些小组件则允许用户进行简单的设置,如启用或禁用某个功能,通常通过一个开关(Switch)来实现。这些小组件可能包含以下特点:
配置意图(AppIntent):开发者在小组件中提供了一个配置界面,通常通过 AppIntent 提供一些简单的开关、选择框或输入框来供用户调整。
配置的内容较简单:这种小组件的配置通常是启用或禁用某个功能(如显示或隐藏内容,开启某个动画,选择某种模式等)。
@Parameter 是用于在 App Intents 中定义配置项的属性包装器。它允许小组件配置提供可自定义的参数。这些参数将显示在小组件的配置界面,供用户调整。可以为这些参数设置不同的类型,根据用户配置的内容来选择合适的数据类型。
@Parameter(title: "摄氏度", default: false)
var temperature: Bool
@Parameter 支持的常见数据类型有:
1、基本数据类型
String:用于文本参数。
@Parameter(title: "User Name", default: "John Doe")
var userName: String
Bool:用于开关类型的配置(如启用/禁用)。
@Parameter(title: "Enable Notifications", default: true)
var enableNotifications: Bool
2、数值类型
Int:用于整数值。
@Parameter(title: "Number of Items", default: 5)
var numberOfItems: Int
Double:用于浮动值,例如百分比、金额等。
@Parameter(title: "Temperature", default: 22.5)
var temperature: Double
3、自定义类型(例如:URL)
URL:可以使用 URL 类型,供用户输入网址或文件路径等。
@Parameter(title: "Website URL", default: URL(string: "https://example.com")!)
var websiteURL: URL
4、数组类型(Multiple Values)
数组类型:可以使用数组来让用户选择多个值。通常,使用 @Parameter 包装一个数组类型的字段,允许多选。
@Parameter(title: "Select Tags", default: ["iOS", "Swift"])
var selectedTags: [String]
完整示例
//
// AppIntent.swift
// BankletWidget
//
// Created by 方君宇 on 2025/2/13.
//
import WidgetKit
import AppIntents
struct ConfigurationAppIntent: WidgetConfigurationIntent {
static var title: LocalizedStringResource = "Configuration"
static var description = IntentDescription("This is an example widget.")
// An example configurable parameter.
@Parameter(title: "User Name", default: "John Doe")
var userName: String
@Parameter(title: "Enable Notifications", default: true)
var enableNotifications: Bool
@Parameter(title: "Number of Items", default: 5)
var numberOfItems: Int
@Parameter(title: "Temperature", default: 22.5)
var temperature: Double
@Parameter(title: "Website URL", default: URL(string: "https://example.com")!)
var websiteURL: URL
@Parameter(title: "Select Tags", default: ["iOS", "Swift"])
var selectedTags: [String]
}
import WidgetKit
import AppIntents
struct ConfigurationAppIntent: WidgetConfigurationIntent {
static var title: LocalizedStringResource = "Configuration"
static var description = IntentDescription("This is an example widget.")
// An example configurable parameter.
@Parameter(title: "User Name", default: "John Doe")
var userName: String
@Parameter(title: "Enable Notifications", default: true)
var enableNotifications: Bool
@Parameter(title: "Number of Items", default: 5)
var numberOfItems: Int
@Parameter(title: "Temperature", default: 22.5)
var temperature: Double
@Parameter(title: "Website URL", default: URL(string: "https://example.com")!)
var websiteURL: URL
@Parameter(title: "Select Tags", default: ["iOS", "Swift"])
var selectedTags: [String]
}
