View in English

  • Apple Developer
    • Get Started

    Explore Get Started

    • Overview
    • Learn
    • Apple Developer Program

    Stay Updated

    • Latest News
    • Hello Developer
    • Platforms

    Explore Platforms

    • Apple Platforms
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    Featured

    • Design
    • Distribution
    • Games
    • Accessories
    • Web
    • Home
    • CarPlay
    • Technologies

    Explore Technologies

    • Overview
    • Xcode
    • Swift
    • SwiftUI

    Featured

    • Accessibility
    • App Intents
    • Apple Intelligence
    • Games
    • Machine Learning & AI
    • Security
    • Xcode Cloud
    • Community

    Explore Community

    • Overview
    • Meet with Apple events
    • Community-driven events
    • Developer Forums
    • Open Source

    Featured

    • WWDC
    • Swift Student Challenge
    • Developer Stories
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Centers
    • Documentation

    Explore Documentation

    • Documentation Library
    • Technology Overviews
    • Sample Code
    • Human Interface Guidelines
    • Videos

    Release Notes

    • Featured Updates
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • Downloads

    Explore Downloads

    • All Downloads
    • Operating Systems
    • Applications
    • Design Resources

    Featured

    • Xcode
    • TestFlight
    • Fonts
    • SF Symbols
    • Icon Composer
    • Support

    Explore Support

    • Overview
    • Help Guides
    • Developer Forums
    • Feedback Assistant
    • Contact Us

    Featured

    • Account Help
    • App Review Guidelines
    • App Store Connect Help
    • Upcoming Requirements
    • Agreements and Guidelines
    • System Status
  • Quick Links

    • Events
    • News
    • Forums
    • Sample Code
    • Videos
 

Videos

Abrir menú Cerrar menú
  • Colecciones
  • Todos los videos
  • Información

Más videos

  • Información
  • Código
  • Extend your app’s controls across the system

    Bring your app's controls to Control Center, the Lock Screen, and beyond. Learn how you can use WidgetKit to extend your app's controls to the system experience. We'll cover how you can to build a control, tailor its appearance, and make it configurable.

    Capítulos

    • 0:00 - Introduction
    • 0:37 - Learn about controls
    • 3:04 - Build a control
    • 6:39 - Update toggle states
    • 12:25 - Make controls configurable
    • 14:40 - Add refinements

    Recursos

    • Creating a camera experience for the Lock Screen
    • Updating controls locally and remotely
    • Adding refinements and configuration to controls
    • Creating controls to perform actions across the system
    • Human Interface Guidelines: Controls
    • Forum: App & System Services
      • Video HD
      • Video SD

    Videos relacionados

    WWDC24

    • Build a great Lock Screen camera capture experience
  • Buscar este video…
    • 3:13 - Add the control to the Widget Bundle

      @main
      struct ProductivityExtensionBundle: WidgetBundle {
          
          var body: some Widget {
              ChecklistWidget()
              TaskCounterWidget()
              TimerToggle()
          }
          
      }
    • 3:29 - Complete the control

      struct TimerToggle: ControlWidget {
          var body: some ControlWidgetConfiguration {
              StaticControlConfiguration(
                  kind: "com.apple.Productivity.TimerToggle"
              ) {
                  ControlWidgetToggle(
                      "Work Timer",
                      isOn: TimerManager.shared.isRunning,
                      action: ToggleTimerIntent()
                  ) { _ in
                      Image(systemName:
                            "hourglass.bottomhalf.filled")
                  }
              }
          }
      }
    • 4:41 - Specify different symbols when on and off​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

      struct TimerToggle: ControlWidget {
          var body: some ControlWidgetConfiguration {
              StaticControlConfiguration(
                  kind: "com.apple.Productivity.TimerToggle"
              ) {
                  ControlWidgetToggle(
                      "Work Timer",
                      isOn: TimerManager.shared.isRunning,
                      action: ToggleTimerIntent()
                  ) { isOn in
                      Image(systemName: isOn
                            ? "hourglass"
                            : "hourglass.bottomhalf.filled")
                  }
              }
          }
      }
    • 5:21 - Specify custom value text​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ and add a custom tint color

      struct TimerToggle: ControlWidget {
          var body: some ControlWidgetConfiguration {
              StaticControlConfiguration(
                  kind: "com.apple.Productivity.TimerToggle"
              ) {
                  ControlWidgetToggle(
                      "Work Timer",
                      isOn: TimerManager.shared.isRunning,
                      action: ToggleTimerIntent()
                  ) { isOn in
                      Label(isOn ? "Running" : "Stopped",
                            systemImage: isOn
                            ? "hourglass"
                            : "hourglass.bottomhalf.filled")
                  }
                  .tint(.purple)
              }
          }
      }
    • 8:14 - Implement timer toggling

      struct ToggleTimerIntent: SetValueIntent, LiveActivityIntent {
          static let title: LocalizedStringResource = "Productivity Timer"
          
          @Parameter(title: "Running")
          var value: Bool  // The timer’s running state
          
          func perform() throws -> some IntentResult {
              TimerManager.shared.setTimerRunning(value)
              return .result()
          }
      }
    • 8:54 - Refresh the control from within the app

      func timerManager(_ manager: TimerManager,
                        timerDidChange timer: ProductivityTimer) {
          ControlCenter.shared.reloadControls(
              ofKind: "com.apple.Productivity.TimerToggle"
          )
      }
    • 10:03 - Define a Value Provider

      struct TimerValueProvider: ControlValueProvider {
          
          func currentValue() async throws -> Bool {
              try await TimerManager.shared.fetchRunningState()
          }
          
          let previewValue: Bool = false
      }
    • 11:00 - Provide asynchronously fetched state with a Value Provider

      struct TimerToggle: ControlWidget {
          var body: some ControlWidgetConfiguration {
              StaticControlConfiguration(
                  kind: "com.apple.Productivity.TimerToggle",
                  provider: TimerValueProvider()
              ) { isRunning in
                  ControlWidgetToggle(
                      "Work Timer",
                      isOn: isRunning,
                      action: ToggleTimerIntent()
                  ) { isOn in
                      Label(isOn ? "Running" : "Stopped",
                            systemImage: isOn
                            ? "hourglass"
                            : "hourglass.bottomhalf.filled")
                  }
                  .tint(.purple)
              }
          }
      }
    • 13:06 - Make the Value Provider configurable

      struct ConfigurableTimerValueProvider: AppIntentControlValueProvider {
          func currentValue(configuration: SelectTimerIntent) async throws -> TimerState {
              let timer = configuration.timer
              let isRunning = try await TimerManager.shared.fetchTimerRunning(timer: timer)
              return TimerState(timer: timer, isRunning: isRunning)
          }
          
          func previewValue(configuration: SelectTimerIntent) -> TimerState {
              return TimerState(timer: configuration.timer, isRunning: false)
          }
      }
    • 13:40 - Make the timer configurable

      struct TimerToggle: ControlWidget {
          var body: some ControlWidgetConfiguration {
              AppIntentControlConfiguration(
                  kind: "com.apple.Productivity.TimerToggle",
                  provider: ConfigurableTimerValueProvider()
              ) { timerState in
                  ControlWidgetToggle(
                      timerState.timer.name,
                      isOn: timerState.isRunning,
                      action: ToggleTimerIntent(timer: timerState.timer)
                  ) { isOn in
                      Label(isOn ? "Running" : "Stopped",
                            systemImage: isOn
                            ? "hourglass"
                            : "hourglass.bottomhalf.filled")
                  }
                  .tint(.purple)
              }
          }
      }
    • 14:26 - Prompt for user configuration automatically

      struct SomeControl: ControlWidget {
          var body: some ControlWidgetConfiguration {
              AppIntentControlConfiguration(
                  // ...
              )
              .promptsForUserConfiguration()
          }
      }
    • 15:42 - Custom action hint -> hint treated as verb phrase

      struct TimerToggle: ControlWidget {
          var body: some ControlWidgetConfiguration {
              AppIntentControlConfiguration(
                  kind: "com.apple.Productivity.TimerToggle",
                  provider: ConfigurableTimerValueProvider()
              ) { timerState in
                  ControlWidgetToggle(
                      timerState.timer.name,
                      isOn: timerState.isRunning,
                      action: ToggleTimerIntent(timer: timerState.timer)
                  ) { isOn in
                      Label(isOn ? "Running" : "Stopped",
                            systemImage: isOn
                            ? "hourglass"
                            : "hourglass.bottomhalf.filled")
                      .controlWidgetActionHint(isOn ?
                                               "Start" : "Stop")
                  }
                  .tint(.purple)
              }
          }
      }
    • 16:56 - Specify a display name and add a description

      struct TimerToggle: ControlWidget {
          var body: some ControlWidgetConfiguration {
              AppIntentControlConfiguration(
                  kind: "com.apple.Productivity.TimerToggle",
                  provider: ConfigurableTimerValueProvider()
              ) { timerState in
                  ControlWidgetToggle(
                      timerState.timer.name,
                      isOn: timerState.isRunning,
                      action: ToggleTimerIntent(timer: timerState.timer)
                  ) { isOn in
                      Label(isOn ? "Running" : "Stopped",
                            systemImage: isOn
                            ? "hourglass"
                            : "hourglass.bottomhalf.filled")
                      .controlWidgetActionHint(isOn ?
                                               "Start" : "Stop")
                  }
                  .tint(.purple)
              }
              .displayName("Productivity Timer")
              .description("Start and stop a productivity timer.")
          }
      }

Developer Footer

  • Videos
  • WWDC24
  • Extend your app’s controls across the system
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • Apple Intelligence
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning & AI
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Downloads
    • Sample Code
    • Videos
    Open Menu Close Menu
    • Help Guides & Articles
    • Contact Us
    • Forums
    • Feedback & Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • Mini Apps Partner Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    Open Menu Close Menu
    • Meet with Apple
    • Apple Developer Centers
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • WWDC
    Read the latest news.
    Get the Apple Developer app.
    Copyright © 2026 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines