Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2025 Health & FitnessMaps & LocationSwiftUI & UI Frameworks

WWDC25 · 21 min · Health & Fitness / Maps & Location / SwiftUI & UI Frameworks

What’s new in watchOS 26

Discover the new features in watchOS 26 and learn how to integrate them into your watchOS and iOS apps. Explore the ARM64 architecture, and dive into the new design system. We’ll also share updates for widgets and insights on how to bring controls to Apple Watch.

Watch at developer.apple.com ↗

Transcript all transcripts

Chapters

  • 0:00 — Introduction
  • 0:56 — Update for watchOS 26
  • 3:48 — Bring apps to new places
  • 9:44 — Be relevant and up-to-date

Code shown on screen · 13 snippets

Make a widget configurable swift · at 6:53 ↗
// In the AppIntentTimelineProvider
func recommendations() -> [AppIntentRecommendation<BeachConfigurationIntent>] {
  return []
}
Support earlier versions of watchOS with a configurable widget swift · at 7:06 ↗
// In the AppIntentTimelineProvider
func recommendations() -> [AppIntentRecommendation<BeachConfigurationIntent>] {
  if #available(watchOS 26, *) {
    // Return an empty array to allow configuration of the widget in watchOS 12+
    return []
  } else {
    // Return array of recommendations for preconfigured widgets before watchOS 12
    return recommendedBeaches
  }
}
Use AppIntentControlConfiguration to make a control configurable swift · at 7:46 ↗
struct ConfigurableMeditationControl: ControlWidget {
  var body: some ControlWidgetConfiguration {
    AppIntentControlConfiguration(
      kind: WidgetKinds.configurableMeditationControl,
      provider: Provider()
    ) { value in
      // Provide the control's content
    }
    .displayName("Ocean Meditation")
    .description("Meditation with optional ocean sounds.")
    .promptsForUserConfiguration()
  }
}
Use AppIntentControlValueProvider for a configurable control swift · at 7:56 ↗
extension ConfigurableMeditationControl {
  struct Provider: AppIntentControlValueProvider {
    func previewValue(configuration: TimerConfiguration) -> Value {
      // Return the value to show in the add sheet
    }

    func currentValue(configuration: TimerConfiguration) async throws -> Value {
      // Return the control's value
    }
  }
}
Relevance for a point-of-interest category swift · at 10:53 ↗
func relevance() async -> WidgetRelevance<Void> {
  guard let context = RelevantContext.location(category: .beach) else {
    return WidgetRelevance<Void>([])
  }
  return WidgetRelevance([WidgetRelevanceAttribute(context: context)])
}
Implement the relevance method in the RelevanceEntriesProvider swift · at 14:37 ↗
struct BeachEventRelevanceProvider: RelevanceEntriesProvider {
  let store: BeachEventStore

  func relevance() async -> WidgetRelevance<BeachEventConfigurationIntent> {
    // Associate configuration intents with RelevantContexts
    let attributes = events.map { event in
      WidgetRelevanceAttribute(
        configuration: BeachEventConfigurationIntent(event: event),
        context: .date(interval: event.date, kind: .default)
      )
    }

    return WidgetRelevance(attributes)
  }
}
Create a RelevanceEntry when the widget is relevant swift · at 15:09 ↗
struct BeachEventRelevanceProvider: RelevanceEntriesProvider {
  func relevance() async -> WidgetRelevance<BeachEventConfigurationIntent> {
    // Return relevance information for the widget
  }
  
  func entry(
    configuration: BeachEventConfigurationIntent,
    context: Context
  ) async throws -> BeachEventRelevanceEntry {
    if context.isPreview {
      return .previewEntry
    }
    return BeachEventRelevanceEntry(
      event: configuration.event
    )
  }
}
Create a placeholder entry to display when the widget is loading swift · at 15:55 ↗
struct BeachEventRelevanceProvider: RelevanceEntriesProvider {
  func relevance() async -> WidgetRelevance<BeachEventConfigurationIntent> {
    // Return relevance information for the widget
  }
  
  func entry(
    configuration: BeachEventConfigurationIntent,
    context: Context
  ) async throws -> BeachEventRelevanceEntry {
    // Return the entry for the configuration
  }
  
  func placeholder(context: Context) -> BeachEventRelevanceEntry {
    BeachEventRelevanceEntry.placeholderEntry
  }
}
Use a RelevanceConfiguration to create a relevant widget swift · at 16:27 ↗
struct BeachEventWidget: Widget {
  private let model = BeachEventStore.shared

  var body: some WidgetConfiguration {
    RelevanceConfiguration
      kind: "BeachWidget
      provider: BeachEventRelevanceProvider(store: model)
    ) { entry in
      BeachWidgetView(entry: entry)
    }
    .configurationDisplayName("Beach Events")
    .description("Events at the beach")
  }
}
Use associatedKind to relate the relevant widget to the timeline widget swift · at 17:31 ↗
struct BeachEventWidget: Widget {
  private let model = BeachEventStore.shared

  var body: some WidgetConfiguration {
    RelevanceConfiguration
      kind: "BeachWidget
      provider: BeachEventRelevanceProvider(store: model)
    ) { entry in
      BeachWidgetView(entry: entry)
    }
    .configurationDisplayName("Beach Events")
    .description("Events at the beach")
    .associatedKind(WidgetKinds.beachEventsTimeline)
  }
}
Create a Preview with relevanceEntries swift · at 18:06 ↗
#Preview("Entries") {
  BeachEventWidget()
} relevanceEntries: {
  BeachEventRelevanceEntry.previewShorebirds
  BeachEventRelevanceEntry.previewMeditation
}
Create a Preview with relevance swift · at 18:26 ↗
#Preview("Provider and Relevance") {
  BeachEventWidget()
} relevanceProvider: {
  BeachEventRelevanceProvider(store: .preview)
} relevance: {
  let configurations: [BeachEventConfigurationIntent] = [
    .previewSurfing,
    .previewMeditation,
    .previewWalk
  ]
  let attributes = configurations.map {
    WidgetRelevanceAttribute(
      configuration: $0,
      context: .date($0.event.startDate, kind: .default)
    )
  }
  return WidgetRelevance(attributes)
}
Create a Preview with a relevanceProvider swift · at 18:47 ↗
#Preview("Provider") {
  BeachEventWidget()
} relevanceProvider: {
  BeachEventRelevanceProvider(store: .preview)
}

Resources