Create Widget Extension

Published by @SoNiceInfo at 7/5/2020

By using Widgets, users can diplay App contents on iOS Home and macOS Notification Center.

Thumbnail image from an article presented at WWDC20 that shows what you need to know to create a Widget Extension and how to create it.

What you need to know about Widgets

Widgets Size

The size of widgets are defined at supportedFamilies. There are 3 types, .systemSmall(2x2 Size), .systemMedium(4x2 Size), .systemLarge(4x4 Size).

StaticConfiguration and IntentConfiguration

There 2 type in Widgets, StaticConfiguration and IntentConfiguration.

  • StaticConfiguration: Users don't need any configuration on widgets, for example, widgets that display lates news.
  • IntentConfiguration: Users can configure on widgets, for example, widgtes that need location info to show weather.

TimelineEntry and Timeline

Widgets don't support real-time update. You need to provide contents with display time to widgets. You need to know TimelineEntry and Timeline.TimelineEntry Object has the contents and the Date-type date like below. (In this case, content is something Int type.) You set date to date when you want to display the contents.

struct SimpleEntry: TimelineEntry {
    var date: Date
    var int: Int

Timeline is an array of TimelineEntry objects. Reload of Timeline is occured at when the last TimelineEntry was displayed (.atEnd), after the specified time has elapsed (.after), App reload content through WidgetCenter(.never). Timeline is provided to widgets by Provider conforming to TimelineProvider.


Snapshot is used for previewing widgets and displaying them instantly in the Widget Gallery. A TimelineEntry is provided to the Snapshot. A mock value should be in the TimelineEntry until the contents will be fetched from servers.


The Provider is an object that provides the above timeline and Snapshot to the widget.
With StaticConfiguration、you use a Provider conforming to TimelineProvider.
With IntentConfiguration、you use a Provider conforming to IntentTimelineProvider.

struct Provider: TimelineProvider {
    public typealias Entry = SimpleEntry

    public func snapshot(with context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date(), int: Int.random(in: 1..<100))

    public func timeline(with context: Context, completion: @escaping (Timeline<Entry>) -> ()) {

        // Generate a timeline consisting of five entries an hour apart, starting from the current date.
        let date = Date()
        let refreshDate = .minute, value: 1, to: date)!

        let timeline = Timeline(entries: [SimpleEntry(date: date, int: Int.random(in: 1..<100)), SimpleEntry(date: refreshDate, int: Int.random(in: 1..<100))], policy: .after(refreshDate))


The Placeholder displays the general look and feel of the widget. You will be able to use .redacted(reason: .placeholder) to implement.


The kind is a string that uniquely identifies the widget. Like com.example.widget, a string like the Bundle indentifier would be good.

Add Widget Extension

Widget technically refers to the Widget Extension that comes with your app.
Go to File → New → Target... then dialog appears, select Widget Extension and press Select.
Check Include Configuration Intent to use IntentConfiguration.
Enter the appropriate Product Name and Finish.

Press Activate when asked when activating "PRODUCT_NAME" scheme.
PRODUCT_NAME.swift will be added in the new directory.
You are now ready to create a Widget Extension.


Select your widget in "Set the active scheme" at top left and built it. IntentConfiguration widgets cannot be test with Xcode 12 beta and iOS Simulator. Let's wait for them to fix it.


Creating a Widget Extension | Apple Developer Documentation
Widgets - System Capabilities - iOS - Human Interface Guidelines - Apple Developer

    I released iOS App!

    ToDo App

    Visualize Activity, Data sharing with iCloud, Dark mode supported.


    IP Address bookmark.

    Check and bookamrk IP address of all interfaces with geolocation.