iOS Setup
On iOS Widgets are an App Extension. The following steps explain how to add the correct App Extension, how to do the basic configuration to read/display data you send from your App in the Widget and how to setup GroupIds to ensure the correct communication between your App and the Widget.
Add a Widget to your App in Xcode
Add a widget extension by going File > New > Target > Widget Extension
Fill in your desired name for the Widget
This documentation is based on a non-configurable Widget. Leave the Include Configuration App Intent option unchecked to follow this example.
If you want build configurable widgets with home_widget follow the documentation for configurable widgets.
However it is advised to read through this page as well, as there are concepts that will be referenced in the other documentation.
The generated Widget code includes the following classes:
TimelineProvider
- Provides a Timeline of entries at which the System will update the Widget automaticallyTimelineEntry
- Represents the Data Object used to build the Widget. Thedate
field is necessary and defines the point in time at which the Timeline would updateView
- The Widget itself, which is built with SwiftUIWidget
- Configuration: Make note of thekind
you set in the Configuration as this is what's needed to update the Widget from Flutter
Widget
In the Widget Configuration it is important to set the kind
to the same value as the name
/iOSName
in the updateWidget
function in Flutter
TimelineEntry / TimelineProvider
Adjust the TimelineEntry
to match your desired Data Structure you need to build your Widget. This entry is what is passed to the actual View
to build the Widget.TimelineEntry
struct CounterEntry: TimelineEntry {
let date: Date
let counter: Int
}
Adjust the TimelineProvider
to build a timeline (can be single entry if all updating is always handled from Flutter) where you create a TimelineEntry
based on the Data stored with HomeWidget.saveWidgetData
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), counter: 0)
}
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
let prefs = UserDefaults(suiteName: "group.YOUR_GROUP_ID")
let counter = prefs?.integer(forKey: "counter")
let entry = CounterEntry(date: Date(), counter: counter ?? 0)
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
getSnapshot(in: context) { (entry) in
let timeline = Timeline(entries: [entry], policy: .atEnd)
completion(timeline)
}
}
}
View
In the View you build your Layout of the Widget. Using the TimelineEntry
you can access the Data you stored in UserDefaults
and build your Widget accordingly
struct WidgetEntryView : View {
var entry: Provider.Entry
var body: some View {
VStack {
Text(entry.counter.description)
}
}
}
For more Information on how to build Widgets in iOS, check out the Apple Documentation
GroupId
home_widget syncs data between your App and the Widget using App Groups.
Note: in order to add groupIds you need a paid Apple Developer Account
Go to your Apple Developer Account and add a new group. Add this group to your Runner and the Widget Extension inside XCode: Signing & Capabilities > App Groups > +.
To swap between your App, and the Extension change the Target)