How do several widgets live in one extension, and what is a widget’s kind used for?
Predict first
Does a bundle of 16 widgets compile?
import WidgetKit
import SwiftUI
struct E: TimelineEntry { let date: Date }
struct P: TimelineProvider {
func placeholder(in context: Context) -> E { E(date: .now) }
func getSnapshot(in context: Context, completion: @escaping (E) -> Void) { completion(E(date: .now)) }
func getTimeline(in context: Context, completion: @escaping (Timeline<E>) -> Void) {
completion(Timeline(entries: [E(date: .now)], policy: .never))
}
}
struct W1: Widget { var body: some WidgetConfiguration { StaticConfiguration(kind: "w1", provider: P()) { _ in Text("1") } } }
struct W2: Widget { var body: some WidgetConfiguration { StaticConfiguration(kind: "w2", provider: P()) { _ in Text("2") } } }
@main struct Bundle16: WidgetBundle {
var body: some Widget {
W1(); W2(); W1(); W2(); W1(); W2(); W1(); W2()
W1(); W2(); W1(); W2(); W1(); W2(); W1(); W2()
}
}
- Yes, it compiles
- No: a bundle is limited to a handful of widgets
- No: @main is not allowed on a bundle
Mental model. The kind is a widget’s passport number: change it and the system sees a stranger.
One widget extension can hold many widgets through a WidgetBundle, and that bundle is the extension’s @main. Each widget has a kind string passed to its configuration; the system uses it to identify the widget, and your app uses it in WidgetCenter.shared.reloadTimelines(ofKind:). The check compiled a bundle with 16 widgets, so the old “five or six widgets per bundle” limit no longer applies on this toolchain. Choose kinds once and never change them: renaming a kind makes the system treat the widget as a new one, and users who added the old one lose it from their Home Screen.
A typo in the kind passed to reloadTimelines(ofKind:) fails silently, so keep kinds as shared constants and reload from the app through one small helper. Use reloadAllTimelines() sparingly; it counts against the budget for every widget. Widgets, Control Center controls (Q407) and Live Activities can share the same bundle. Not run: how the gallery lists them, which needs a device or simulator UI.
WidgetBundle accepts this many widgets in one builder.
Common traps
- Renaming a kind in a release. Existing placed widgets disappear.
- Reloading by a mistyped kind. Nothing reloads and nothing reports it.
They might follow up with
- Can I find what the user placed?
WidgetCenter.shared.getCurrentConfigurationsreturns the placed widgets, so you can reload only what exists.
Related questions
- 19.4.1 How does a WidgetKit widget work: providers, timeline entries, reload policies, families and the refresh…
- 19.4.2 How do configurable widgets, interactive buttons and Control Center controls work with App Intents?
- 19.7.2 How do you treat extensions, widgets and intents as a public API of the product: shared modules, data…
← How do you unit test a widget’s timeline logic when the provider’s… How do widgets adapt to the tinted Home Screen and the Lock Screen… →