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

iOS17自定义AppEntity在WidgetConfiguration的ParameterSummary中失效问题

iOS17 Widget配置中AppEntity与ParameterSummary的条件判断失效问题

我们正尝试利用iOS17的交互式Widget特性,通过widgetMode配置Widget,不同模式对应仅在该模式下显示的特定参数。自定义了WidgetMode作为AppEntity类型,代码如下:

struct WidgetMode: AppEntity, Equatable {
    var id: Int
    static var defaultQuery = WidgetQuery()

    static var typeDisplayRepresentation: TypeDisplayRepresentation = TypeDisplayRepresentation(name: LocalizedStringResource("Mode"))

    var displayRepresentation: DisplayRepresentation {
        switch id {
        case 0:
            return DisplayRepresentation(title: LocalizedStringResource("Favorites"))
        case 1:
            return DisplayRepresentation(title: LocalizedStringResource("Recents"))
        case 2:
            return DisplayRepresentation(title: LocalizedStringResource("Categories"))
        case 3:
            return DisplayRepresentation(title: LocalizedStringResource("Collections"))
        default:
            return DisplayRepresentation(title: LocalizedStringResource("Unknown"))
        }
    }

    static func == (lhs: WidgetMode, rhs: WidgetMode) -> Bool {
        lhs.id == rhs.id
    }
}

struct WidgetQuery: EntityQuery {
    func entities(for identifiers: [Int]) async throws -> [WidgetMode] {
        [0, 1, 2, 3].map({ WidgetMode(id: $0)})
    }
    func suggestedEntities() async throws -> [WidgetMode] {
        [0, 1, 2, 3].map({ WidgetMode(id: $0)})
    }
}

随后借助新的ParameterSummary特性,尝试根据不同模式控制输入参数显示,代码如下:

struct ConfigurationAppIntent: WidgetConfigurationIntent {
    static var title: LocalizedStringResource = "Configuration"
    static var description = IntentDescription("Choose what to show")

    @Parameter(title: LocalizedStringResource("Show"))
    var widgetMode: WidgetMode

    @Parameter (title: "Category")
    var category: CategoryDetail?

    static var parameterSummary: some ParameterSummary {
        When(\.$widgetMode, .equalTo, WidgetMode(id: 2)) {
            Summary {
                \.$widgetMode
                \.$category
            }
        } otherwise: {
            Summary {
                \.$widgetMode
            }
        }
    }
}

但When语句完全忽略.equalTo条件,始终进入otherwise分支。测试发现将widgetMode替换为Bool或Int类型时功能正常。请问使用AppEntity与ParameterSummary是否存在未知限制?实现是否有误?或是iOS17/Xcode稳定版的bug?


问题原因与解决方案

问题出在自定义AppEntity类型的相等性判断逻辑在ParameterSummary的When条件中不生效——Intent框架处理AppEntity的条件匹配时,并不依赖你手动实现的Equatable协议,而是默认使用实体的标识符(identifier)进行匹配,这和Bool、Int这类基础类型的直接值匹配逻辑不同。

解决步骤:

  1. 在When条件中改用基于实体标识符的匹配方式,通过.identifier参数指定要匹配的WidgetMode的id字符串形式:

修改后的parameterSummary代码:

static var parameterSummary: some ParameterSummary {
    When(\.$widgetMode, .equalTo, identifier: "2") {
        Summary {
            \.$widgetMode
            \.$category
        }
    } otherwise: {
        Summary {
            \.$widgetMode
        }
    }
}
  1. 确认标识符匹配逻辑:
    默认情况下,AppEntity的标识符是其id属性的字符串表示(如果你的实体没有自定义标识符逻辑)。如果需要自定义标识符,可让WidgetMode实现EntityIdentifierConvertible协议,显式指定标识符的生成规则。

补充说明

这并非iOS17/Xcode的bug,而是对AppEntity在ParameterSummary中的使用规则理解偏差——基础类型直接匹配值,而自定义AppEntity则需要通过标识符进行匹配,框架内部不会调用你实现的==方法来做条件判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 01:00:30