iOS Lockscreen Widgets with Flutter and home_widget

Anton Borries
4 min readOct 14, 2023

--

Recently I started learning Italian with Duolingo and noticed that the iOS App has a Lockscreen Widget with their mascot bird Duo and the current streak.

This sparked the idea of checking if it is possible to use my package home_widget to create a Lockscreen widget with the best bird mascot there is

Turns out it is super easy!

Note the following steps build upon the Counter App/Widget created in this Article for interactive widgets

Creating the Widget Image

To create the Widget I am using the renderFlutterWidget method of home_widget to save a Flutter Widget as an image to use in the native widget.

For this I used one of the Dash illustrations by Alex Bradt created for the F3 event and added the current counter value on top (with a bit of eyeballed transformation).

Stack(
children: [
Positioned.fill(
child: Padding(
padding: const EdgeInsets.all(30.0),
child: Image.asset('assets/dash_sign_small.png'),
),
),
Transform.rotate(
angle: 5 * pi / 180,
child: Transform.translate(
offset: const Offset(58, 29),
child: SizedBox(
height: 100,
width: 134,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: FittedBox(
fit: BoxFit.contain,
child: Center(
child: Text(
count.toString(),
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 70,
color: Colors.white,
),
textAlign: TextAlign.center,
),
),
),
),
),
),
),
],
)

When updating the value I save a rendering of that Widget using renderFlutterWidget

await HomeWidget.renderFlutterWidget(
DashWithSign(count: value ?? 0),
key: 'dash_counter',
logicalSize: const Size(100, 100),
);

Overall I think especially for smaller Widgets like this the renderFlutterWidget method is ideal for Flutter developers as I would assume most of us are way more efficient to write intricate widgets like this in Flutter than building things like this in SwiftUI.

When using this make sure to keep the following points in mind:

  1. You should check how your Widget looks after iOS applies the tinting on the Lockscreen as it will adjust it to a uniform color that might also be influenced by the wallpaper of the user.
  2. Remember that for the some configurations iOS will clip the widget to a circle so make sure that you add adequate padding to your widget

The native part

Writing native iOS code can be scary but if you managed to get through the example for the counter app you should nail this! Especially as the Widget itself is super easy when using a rendered Flutter Widget

Add the supported family

In iOS Lockscreen Widgets are called AccessoryWidgets and can be added as a supportedFamily to your WidgetConfiguration

var body: some WidgetConfiguration {
...
.description("Count the Number Up")
.supportedFamilies([
.systemSmall,
.systemMedium,
.accessoryCircular
])

The important family here is .acessoryCircular Here you can also define which sizes you want to support in general. For a list of all possible families check this page by Apple.

Adjust the Layout for the Widget

When building the Widget we need to detect which widgetFamily we are building and in that case return our pre rendered Image.

struct CounterWidgetEntryView: View {
var entry: Provider.Entry

// Detect the current Family
@Environment(\.widgetFamily) var family

var body: some View {
if family == .accessoryCircular {
Image(
uiImage: UIImage(
contentsOfFile: UserDefaults(suiteName: "YOUR_APP_GROUP")?.string(
forKey: "dash_counter") ?? "")!
).resizable()
.frame(width: 76, height: 76)
.scaledToFill()
} else {
// Build Widget for other families
}
}
}

Thats already it. Now if you run the App you should be able to add the widgets to your HomeScreen.

You could of course also create a new Widget Target for the widgets if you want to add more

Conclusion

All in all extending your App to the iOS lockscreen is super quick (especially if you are already using home_widget) and allows you to give users access to your Apps even more.

Links

The full repository of this example is here:

With the changes made for this article in this commit.

If you have any questions regarding this feel free to reach out to me on Twitter/X

Check out/Like home_widget on pub.dev

Check out/Star Open PRs/Issues for home_widget on github

Check out Alex Bradt who did the amazing Dash Illustration

--

--