Control Center Widget: Unable to read configuration from ControlConfigurationIntent in SetValueIntent

I've created a control centre widget modelled on the talk in "Extend your app's controls across the system".

In the talk, the user can select which timer they want to start ("work" or "violin").

The specific timer is passed to ToggleTimerIntent as follows:

ControlWidgetToggle(
    timerState.timer.name,
    isOn: timerState.isRunning
    action: ToggleTimerIntent(timer: timerState.timer)
) { isOn in
    ...
}

However, I can't find a way to access the timer value from inside my ToggleTimerIntent, since this code isn't provided in the talk.

An AppIntent must provide an empty init(), so I've specified timer as an option String:

@available(iOS 18, *)
struct ToggleTimerIntent: SetValueIntent {
    static let title: LocalizedStringResource = "Toggle Timer"

    // This value isn't never populated.
    var timer: String?

    @Parameter(title: "Running")
    var value: Bool

    func perform() async throws -> some IntentResult {

        if let timer {

        }
        else {
            // Always here
        }
    }
}

When I backtrace the code, ToggleTimerIntent is instantiated several times, however perform() is only called on an instance where the timer value isn't provided.

Answered by CrunchyBagel in 797550022

Just to close the loop on this: when creating a widget extension, Xcode has a template to create this timer, which it does as follows:

struct StartTimerIntent: SetValueIntent {
    static let title: LocalizedStringResource = "Start a timer"

    @Parameter(title: "Timer Name")
    var name: String

    @Parameter(title: "Timer is running")
    var value: Bool

    init() {}

    init(_ name: String) {
        self.name = name
    }

    func perform() async throws -> some IntentResult {
        // Start the timer…
        return .result()
    }
}

So anyway, the timer name needs to be marked as @Parameter, and mustn't be optional.

Accepted Answer

Just to close the loop on this: when creating a widget extension, Xcode has a template to create this timer, which it does as follows:

struct StartTimerIntent: SetValueIntent {
    static let title: LocalizedStringResource = "Start a timer"

    @Parameter(title: "Timer Name")
    var name: String

    @Parameter(title: "Timer is running")
    var value: Bool

    init() {}

    init(_ name: String) {
        self.name = name
    }

    func perform() async throws -> some IntentResult {
        // Start the timer…
        return .result()
    }
}

So anyway, the timer name needs to be marked as @Parameter, and mustn't be optional.

Control Center Widget: Unable to read configuration from ControlConfigurationIntent in SetValueIntent
 
 
Q