Principles of Great Widgets - WWDC21

Peter Yaacoub •


Introduction

Creating effective widgets requires understanding their update mechanics, location-based features, and design principles. This article outlines key points from the WWDC21 session on crafting exceptional widgets, focusing on how to optimize their functionality and user experience.

Time

Widgets update at intervals measured in minutes and hours, not seconds. Highly viewed widgets can receive between 40 to 70 updates per day. Below is a summary of different update methods:

  Budgeted Free
TimelineReloadPolicy  
WidgetCenter ~
Significant location change  
System update  

TimelineReloadPolicy

  • atEnd: For content that continuously updates.
  • after(_:): For unpredictable content, but be cautious of server overload if many users trigger updates simultaneously.
  • never: For static content, utilize WidgetCenter reload methods for updates.

Location

Widgets can provide location-specific content by setting the NSWidgetUsesLocation property to true in the Info.plist (documentation not found). Use CLLocationManager in the timeline provider to check user authorization with the isAuthorizedForWidgetUpdates property.

Location Permissions

Location permission Widget’s access
Never  
Allow once  
While using app ~
While using app or widgets ~
Always

Design

Widgets adapt to light and dark modes using SwiftUI. They can also maintain a consistent brand style, independent of the theme. iPadOS supports an extra-large widget variant, providing more design flexibility.

Privacy-Sensitive Information

For privacy-sensitive content, use the privacySensitive(_:) view modifier and set the com.apple.developer.default-data-protection entitlement to NSFileProtectionComplete.

Example Code Snippet:

Text("Sensitive Info")
    .privacySensitive()

Widget Configuration

Widgets are part of a WidgetBundle, ordered by importance. Configuration options include StaticConfiguration and IntentConfiguration, offering diverse customization for optimal user experience.

struct MyWidget: Widget {
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: "com.example.mywidget", provider: Provider()) { entry in
            MyWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("My Widget")
        .description("This is an example widget.")
    }
}

Conclusion

Adhering to these principles ensures that your widgets are functional, user-friendly, and visually appealing. By understanding update mechanics, leveraging location features, and following design best practices, you can create widgets that enhance the user experience and add significant value to your app.