- Possibilities, design good practices and limitations
- Xcode 12 generated widget code overview
- Create a basic widget — Coming soon
- Create an advanced widget — Coming soon
Creating a widget is not complex but can quickly take time. While a very simple widget can be done very fast, a real, well-made case will take more time to deal with all of the scenarios and ensure that the widget is always in good state with the application. You should know that widgets are necessarily created in SwiftUI, but don’t panic, even applications using UIKit can benefit from it.
Widget creation with Xcode 12
File > New > Target
Then choose Widget extension
Finally, you must indicate the name of the target as well as the application for which you want to create this target (in the case where you have a dev app and a prod app for example).
Particular point on this last step of creating the widget target: you have to choose whether you want to include “Configuration Intent”. If we check this option, we’ll be able to add options directly from the widget (without opening the application), while if we do not check it, our configuration will be static (no option directly from the widget).
To put it simply, we are going to start creating our widget without checking this option, but we will come back to it later (in a future article).
Generated code by Xcode 12
When creating a widget, Xcode only generates 3 things for us:
- the Assets folder (for managing images, colors, etc)
- the Info.plist file (for the global configuration of the widget)
- the widget code (the most interesting part)
By opening the main widget file, we can see that it contains quite a few things:
Main definition of the widget
This struct allows to define the widget as such. With this definition that we can choose whether we want a static or dynamic widget (the intents as we saw earlier). It also allows us to define the provider that you’ll use to provide the data to the widget and the view that you want to use. And finally, it’s also this definition that allows us to choose the name you want to give to the widget as well as its description (visible in the iOS widget library).
The provider is divided into three parts: the placeholder, the snapshot and the timeline.
The placeholder allows us to define the view that we want to display during the loading of the widget with the real information. In reality, this view will be used in “skeleton” mode by iOS. Usually, we’ll use the same view we use for our widget with the only difference being that we’ll use fake data to make the loading of the placeholder as fast as possible.
The snapshot allows us to define the view we want to display in the iOS widgets library. Unlike the placeholder, here we can take a little longer to fetch real information to display to the user. It’s even recommended: it will show the user that the widget is responding well to the current state of their application.
The timeline will be used to prepare the different entries to display over time in our widget: we define several dates on which we ask the widget to update to display the new information.
In the code that was generated by Xcode, we can see that we generate 5 entries one hour apart from the current time. Then we choose a Timeline with the policy
atEnd, which will have the effect of refreshing the widget every hour to display these different entries. Actually, there are several strategies for refreshing the widget, but we will come back to that later (in the next article).
The template that will be used to display the data in the widget.
This structure must necessarily inherit from
TimelineEntry so that it can be used with our widget. In fact, it forces us to have a date (used for our widget’s refresh strategy). Obviously, if your model becomes too complicated, do not hesitate to divide it into several substructures.
In this case, since the purpose of the widget generated by Xcode is to display times, the date is more than enough.
The view and it’s preview
Since the widgets are created in SwiftUI only, we end up with a classic SwiftUI view. This view takes an entry (which corresponds to our model) as a parameter, and then displays the information we want to see in our widget.
The preview use the SwiftUI view with a fake entry, which allows us to use the SwiftUI previews to ensure that the widget is correctly rendered in different states (light and dark mode, at a certain date, etc).
The only small thing to be careful of here: the preview must specify a
previewContext, otherwise Xcode will refuse to display the preview. This is not bad because it allows us to choose whether we want to see the rendering for an S, M or L widget.
Xcode widget generated code result
Unsurprisingly after seeing the code, we end up with something very simple that displays the time centered vertically and horizontally in our widget (for S, M and L sizes).
If you missed the previous article, you can read it here: Possibilities, design good practices and limitations.
Then, you can see Create a basic widget (Coming soon) or Create an advanced widget(Coming soon) if you want to learn more about Widgets and how to create them.
And don’t forget to “clap” and share this article if you like it and want to see more content like this! 👏
Thanks for reading,