swiftswiftuiwidgetkit

Widget parameter default value is ignored


I have a widget that accepts two user-defined parameters: location, and background.

The location selector works perfectly and defaults to what my LocationQuery defaultResult specifies. But the background selector for some reason ignores my BackgroundQuery defaultResult and XCode throws this warning:

Error getting AppIntent from LNAction: AppIntent has missing parameter value for 'background'. You may need to set a default value in the initializer of your @Parameter, or using the default method on your Query.
No AppIntent in timeline(for:with:)

Why isn't it working as the location selector does?

struct BackgroundQuery: EntityQuery {
    func entities(for identifiers: [String]) ->  [WidgetBackground]  {
        [
            WidgetBackground(id: "Background1"),
            WidgetBackground(id: "Background2")
        ].filter { identifiers.contains($0.id) }
    }
    
    func suggestedEntities() -> [WidgetBackground] {
        [
            WidgetBackground(id: "Background1"),
            WidgetBackground(id: "Background2")
        ]
    }
    
    func defaultResult() -> WidgetBackground {
        return WidgetBackground(id: "Background1")
    }
}

struct WidgetBackground: AppEntity {
    var id: String
    
    static var typeDisplayRepresentation: TypeDisplayRepresentation = "Background"
    static var defaultQuery = BackgroundQuery()
    
    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(title: "\(NSLocalizedString(id, comment: "").description)")
    }
    
    init(id: String) {
        self.id = id
    }
}


struct LocationQuery: EntityQuery {
    func entities(for identifiers: [LocationDetail.ID]) async throws -> [LocationDetail] {
        LocationDetail.getAllLocations().filter { identifiers.contains($0.id) }
    }
    
    func suggestedEntities() async throws -> [LocationDetail] {
        LocationDetail.getAllLocations()
    }
    
    func defaultResult() async -> LocationDetail? {
        try? await suggestedEntities().first
    }
}



struct SelectLocationIntent: WidgetConfigurationIntent {
    static var title: LocalizedStringResource = "Avalanche Reports Location"
    static var description = IntentDescription("Select the location of the displayed avalanche reports.")

    @Parameter(title: "Location")
    var locationDetail: LocationDetail
    
    @Parameter(title: "Background")
    var background: WidgetBackground
}

Solution

  • Answering my own question because I finally found a solution, it looks like defaultResult only works if its return value is suggestedEntities().first, I honestly have no idea of why it works this way so I would love a better answer where it's explaining and I would mark it as correct.

    func defaultResult() -> WidgetBackground? {
        suggestedEntities().first
    }