Control Center Widget
Learn how EasyAppSwiftUI integrates Control Center widgets
Overview
EasyAppWidgetControl targets iOS 18 Control Center widgets, enabling users to toggle an in-app timer from Control Center or the Lock Screen. This guide explains the control configuration, value provider, and how to extend the control with more actions.
Core Structure
- Control entry
EasyAppWidgetControlconforms toControlWidgetand registers throughAppIntentControlConfiguration. - Value model The nested
Valuestruct keeps track of the control state (isRunning,name). - Intent setup
TimerConfigurationandStartTimerIntentlet users edit the timer name and push state updates into the system.
Key implementation resides in EasyAppSwiftUI/EasyAppWidget/EasyAppWidgetControl.swift:
struct EasyAppWidgetControl: ControlWidget {
static let kind: String = "sunshineLixun.EasyAppSwiftUI.EasyAppWidget"
var body: some ControlWidgetConfiguration {
AppIntentControlConfiguration(
kind: Self.kind,
provider: Provider()
) { value in
ControlWidgetToggle(
"Start Timer",
isOn: value.isRunning,
action: StartTimerIntent(value.name)
) { isRunning in
Label(isRunning ? "On" : "Off", systemImage: "timer")
}
}
.displayName("Timer")
.description("A an example control that runs a timer.")
}
}Provider & State
Providerconforms toAppIntentControlValueProvider, returning the widget value for previews and live usage.currentValuecurrently returnstrueto represent an active timer—replace this stub with real logic that checks application state.
struct Provider: AppIntentControlValueProvider {
func previewValue(configuration: TimerConfiguration) -> Value {
EasyAppWidgetControl.Value(isRunning: false, name: configuration.timerName)
}
func currentValue(configuration: TimerConfiguration) async throws -> Value {
let isRunning = true // Check if the timer is running
return EasyAppWidgetControl.Value(isRunning: isRunning, name: configuration.timerName)
}
}Intent Definitions
TimerConfigurationallows customization of the timer name within the Control Center editor.StartTimerIntentimplementsSetValueIntentto perform the side effect of toggling the timer (currently a stub returning.result(); integrate your business logic here).
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
func perform() async throws -> some IntentResult {
// Start the timer…
return .result()
}
}Integration Steps
- Use Xcode 16 or later and enable the Control Center Widgets capability on the target.
- Include
EasyAppWidgetControl()inEasyAppWidgetBundle.swiftto register the control:@main struct EasyAppWidgetBundle: WidgetBundle { var body: some Widget { EasyAppWidget() EasyAppWidgetLiveActivity() EasyAppWidgetControl() } } - Build and install the app on a device running iOS 18, then open the Control Center or Settings editor to add the Timer control.
- Tapping the control triggers
StartTimerIntent, allowing you to execute timer logic in the intent handler.
Customization Tips
- Adjust the
ControlWidgetTogglestrings or swap inControlWidgetButtonfor other interaction patterns. - Extend the
Valuestruct to surface additional state (e.g., remaining time) and return it from the provider. - Utilize
LocalizedStringResourceto localize the display name and description; update localization files accordingly.
Debugging & Known Issues
- Control missing: ensure the widget extension targets iOS 18+ and test on physical hardware (Control Center widgets are not available in the simulator yet).
- State not refreshing: verify the real data source and call the forthcoming Control Center APIs or
WidgetCenter.shared.reloadAllTimelines()when appropriate. - Intent not firing: double-check
StartTimerIntent.perform()and confirm App Intents entitlements are enabled in the main app. - Kind collisions: keep
kindunique to avoid conflicts with other widgets in the bundle.
By integrating EasyAppWidgetControl, you can extend the EasyApp experience into the Control Center, complementing the Home Screen, Lock Screen, and Dynamic Island widgets.
Last updated on