WidgetKit in iOS

Widgets are mainly designed to let smartphone users see the essential information of any installed app instantly on the home screen of their smartphone. 

A widget is a mini screen of an installed app. Some phones have a widget regarding weather updates, and therefore, such a widget is a mini screen of the weather app installed on the phone. Therefore, you do not have to open the app and check the required details from the widgets on the home screen. 

Hence, a widget provides quick access to information from installed apps without the need for opening the apps. you can add and remove widgets as per your requirements on your smartphones. Widgets are designed for user convenience and personalization.

The WidgetKit framework was introduced in iOS 14 as a simple tool for creating Home Screen Widgets. Since then, it has evolved into a framework that powers some of iOS 16's most anticipated features, such as the Lock Screen Widget, Live Activities, and Dynamic Islands.

Let's explore the basics of creating your first Home Screen Widget.

Widget Family

In WidgetKit, Apple provides an enumeration that defines a widget’s size and shape. There are three sizes (from iOS 14):

  • systemSmall,

  • systemMedium,

  • systemLarge. 

In addition to iPad's large screen and for users' convenience, systemExtraLarge was added from iPadOS 15.

There are other widget families, especially for the lock screen widgets.

  • accessoryCircular,

  • accessoryRectangular,

  • accessoryInline

In this article, we will build a simple Home Screen Widget that displays photos and widget dimension size in the widget.

test

Adding a Widget Extension

All iOS widgets must link to an iOS app. 

In Xcode, once the iOS app is created, then you can add a widget extension by following the steps

Select File > New > Target and create a new widget extension target and name it "PhotoWidget" and Uncheck “Include Live Activity” and "Include Configuration Intent" because it is beyond our scope for now. 

I will cover that in detail in a future article.

testtesttest

You will be prompted to activate the widget extension scheme after adding the new target. Go ahead and activate it.

test

Now delete all auto-generated code in the PhotoWidget file.

Create a Widget

A widget consists of 4 main components:

  • Timeline Entry

  • Widget View (SwiftUI View)

  • Timeline Provider

  • Widget Configuration

Let’s discuss and implement each of these components one by one.

Timeline Entry

As per the Apple document timeline entry is a type that specifies the date to display a widget, and, optionally, indicates the current relevance of the widget’s content.

You can imagine the timeline entry as the model object of the widget view. At least one date parameter must be included. You can add any other parameters in the timeline entry based on your own needs.

The system will display/refresh the widget's data according to the date specified in the timeline entry.

Let’s name the timeline entry as PhotoWidgetEntry

test

Here we will use the imgUrl parameter to hold the information related to the timeline provider and show it on the widget - more on that later.

Widget View

After creating a timeline entry, we can continue to implement the Widget’s UI. it's basically just a SwiftUI View.

test

We are getting an imgUrl from PhotoWidgetEntry and getting an image from that url to display In PhotoWidgetView.

Timeline Provider

The timeline provider provides information to the system about what is to be shown on the widget at a specific timestamp.

The timeline provider must conform to the TimelineProvider protocol which has the following 3 method requirements.

test

Also, be sure to typealias Entry to the PhotoWidgetEntry

Now we will understand the above 3 methods one-by-one.

The first method is the placeholder(in:) method. It is providing dummy data to the system to render a placeholder UI while waiting for the widget to get ready. Notice that SwiftUI will apply a redaction effect to the dummy data we provide so that the actual value of the dummy data is not important.

testtest

Widget in placeholder state

Next method is getSnapshot(in:completion:) and this function mainly provides the data required by the system to render the widget in the widget gallery.

testtest

You can see that the widget is actually showing the flower image we provided “https://source.unsplash.com/random/?flower”

Last method is the getTimeline(in:completion:) This is a very important method in the timeline provider because it provides an array of timeline entries for the current time and, optionally, any future times to update a widget.

As our widget is just showing static data, we can return only 1 timeline entry like so.

test

We have used atEnd refresh policy in the above Timeline. Now we are going to understand the refresh policy.

Refresh Policy

atEnd: WidgetKit can start the next refresh session right after the previous one is completed. There is no guarantee the next session will start immediately as the system will decide the best time to kick off the next refresh session.

after(Date): WidgetKit can only start the next refresh session after a specific date and time. Just like atEnd, the system will decide when is the best time to start the next refresh session.

Never: WidgetKit will not start another refresh session until we explicitly call reloadTimelines(ofKind:) in the hosting app. The refresh session will start immediately after reloadTimelines(ofKind:) is called.

We can finally configure the widget now.

Widget Configuration

This is where we assemble everything we just implemented.

test

The main purpose of the widget configuration is to link up the timeline provider and widget view. We are using StaticConfiguration here. StaticConfiguration means that our widget does not have any user-configurable properties. We should use IntentConfiguration if we want to add any user-configurable properties to our widget.

There are many types of modifiers we can use to further configure the widget configuration. We can use configurationDisplayName modifier to display the widget gallery title and the description modifier to display subtitles.

Now we are going to call PhotoWidget in PhotoWidgetBundle.

test

You can notice the @main attribute here. It indicates that the PhotoWidgetBundle is the entry point for our widget extension.

We have completed the simple PhotoWidget implementation.

Some Reference

https://developer.apple.com/documentation/widgetkit/keeping-a-widget-up-to-date

https://swiftsenpai.com/development/getting-started-widgetkit/

Wrapping Up

In this blog, you have learned the very basics of WidgetKit. We discussed how to show a widget. There is still a lot more to cover and explore.

Widgets literally make life easy for smartphone users. They are now an essential part of every smartphone. Apart from clock, weather, and calendar widgets, you should try out the other available widgets on your phone so that you can enhance your productivity and save a lot of time.

Thank you for reading.

Piyush Sinroja

Sr. Software Engineer - iOS

Published: Jul 21, 2023

Updated: Jul 24, 20236 min read

AWS Certified Team

Tech Holding Team is a AWS Certified & validates cloud expertise to help professionals highlight in-demand skills and organizations build effective, innovative teams for cloud initiatives using AWS.

By using this site, you agree to thePrivacy Policy.