Widgets – Reloading a widget from an app scene

Our apps can trigger widgets to update by reloading all the timelines.

Overview

This article is part of a series on working with widgets in visionOS.

Sometimes we may need to communicate changes in an app to widgets. For example, in Looming Deadlines, if I change the date for a deadline, any related widget should be updated. If we’re using short timeline intervals we may see the update right away. But if we need more control, we can ask WidgetCenter to update the widget. This works by invalidating the current timeline and generating a new one. From WWDC 2025:

The WidgetCenter API is another option available to apps. Inside an app, if a data change occurs that should be reflected in its widget, WidgetCenter’s reloadAllTimelines or reloadTimelines(ofKind:) method can be called. This tells WidgetKit that the widget’s content is outdated and needs to be reloaded. WidgetKit then requests a timeline from the widget extension to update the widget.

What’s new in Widgets

We can reload all timelines for all widgets or reload only the timeline for specific widget.

// Reload all timelines for all widgets
WidgetCenter.shared.reloadAllTimelines()

// Reload timeline for a widget
WidgetCenter.shared.reloadTimelines(ofKind: "MoodWidgets")

This example provides a simple UI in the main window to update a value in user defaults. Both the app and the widget were added to an app group so they can read from the same data store. When we tap one of the buttons, the app will save a new value to user defaults, then ask WidgetCenter to reload the timeline.

private func saveEmojiToUserDefaults(_ emoji: String) {
    sharedUserDefaults.set(emoji, forKey: "dataEmojiExample")
    WidgetCenter.shared.reloadTimelines(ofKind: "MoodWidgets")
}

The widget simply reads a value from user defaults on each refresh.

struct MoodWidgetsEntryView : View {
    var entry: MoodProvider.Entry

    var body: some View {
        VStack {
            Text(getCurrentEmoji())
                .font(.system(size: 60))
        }
    }
    
    private func getCurrentEmoji() -> String {
        return sharedUserDefaults.string(forKey: "dataEmojiExample") ?? "🤷🏻‍♂️"
    }
    
    private var sharedUserDefaults: UserDefaults {
        return UserDefaults(suiteName: "group.com.radicalappdev.StepIntoWidgets") ?? UserDefaults.standard
    }
}

Video Demo

Support our work so we can continue to bring you new examples and articles.

Download the Xcode project with this and many more examples from Step Into Vision.
Some examples are provided as standalone Xcode projects. You can find those here.

Questions or feedback?