Live Activity — What It Is, Widgets on the Lock Screen

Author: IT Sectr Published: 2026-02-15 Reading time: 9 min

Live Activity is a dynamic widget on iPhone Lock Screen and in Dynamic Island, displaying real-time information: delivery status, sports scores, timers and music playback. It is implemented through ActivityKit (Swift, iOS 16.1+) together with WidgetKit. Live Activity updates locally or via push notifications, supports multiple states and is terminated by the system after the event ends. Learn more at ActivityKit Documentation.

Key Takeaways

  • Live Activity — real-time widget on Lock Screen and Dynamic Island
  • ActivityKit — framework for starting and managing Live Activities in iOS 16.1+
  • Push Updates — server sends new state via ActivityKit push notifications
  • States — each Activity supports active and ended states with different UIs
  • Dynamic Island — compact display of Live Activity on iPhone 14 Pro and newer

What is Live Activity — Widget on Lock Screen?

Live Activity is an extension of WidgetKit that displays dynamic content on the iPhone Lock Screen and in Dynamic Island. Unlike a static widget that updates on a system timer, Live Activity is launched by the app and lives for a limited time — up to 8 hours for an active Activity and up to 4 hours after completion. The user sees up-to-date data without unlocking the device: delivery order status, distance to destination in a taxi, match results or workout progress.

ActivityKit is a framework for working with Live Activities, introduced in iOS 16.1. It provides an API for requesting, updating and ending Activities. An Activity is an object with content and state. Content (ActivityContent) defines static data, while state (ActivityState) defines dynamic data that changes over time. The system itself decides when to render new state — this saves battery and guarantees smooth animations.

Each Live Activity is uniquely identified by an ActivityID and is tied to one process — the app that created it. The system may end the Activity when memory is low or battery charge is insufficient. The developer receives a notification of forced termination via the ActivityKit delegate and can save the last state for restoration.

ActivityKit and WidgetKit Architecture

Live Activity Architecture is built on two frameworks: WidgetKit handles SwiftUI view rendering, ActivityKit handles the Activity lifecycle. The developer creates a WidgetBundle with LiveActivityConfiguration support. Each configuration defines the data type (Attributes and State) and a SwiftUI View that the system renders on Lock Screen and Dynamic Island. Data is passed through ActivityAttributes — a struct with let fields for content and var fields for state.

ComponentPurposeAPI
AttributesStatic data of the entire Activitylet name: String, let icon: String
ContentStateDynamic state, modified on updatevar progress: Double, var status: Status
ActivityRequest and management object for ActivityActivity.request(attributes:content:)
PushTokenToken for server push updatesactivity.pushToken publisher
ActivityUISwiftUI View for Lock Screen and Dynamic IslandLockScreenView, ExpandedView, CompactView

Activity Lifecycle includes three phases: active (system displays and updates), final (activity ended but UI still visible for 4 hours), removed (system removes UI). The app can end the Activity at any time. The system also ends Activities forcibly — for example, on device restart or when the 8-hour limit expires.

swift
import ActivityKit

struct DeliveryAttributes: ActivityAttributes {
    public struct ContentState: Codable & Hashable {
        var status: DeliveryStatus
        var estimatedMinutes: Int
    }
    var orderNumber: String
    var restaurantName: String
}

WidgetBundle registers Live Activity via the @main macro: the widget returns a list of configurations including LiveActivityConfiguration. Based on this configuration, the system knows what data types to expect and how to render UI in different states — compact, minimal and expanded for Dynamic Island.

Creating Live Activity with WidgetKit and SwiftUI

Creating an Activity starts with a request to ActivityKit. The app calls Activity.request(attributes:content:pushType:) with initial data. The system checks whether Dynamic Island is available on the device and returns an Activity object. The request may fail if the Active Activity limit is exceeded — typically no more than 5 simultaneously. After a successful request, the system displays the widget on Lock Screen and, if available, in Dynamic Island.

swift
let attributes = DeliveryAttributes(
    orderNumber: "A-1234",
    restaurantName: "Pizza House"
)

let initialState = DeliveryAttributes.ContentState(
    status: DeliveryStatus.preparing,
    estimatedMinutes: 30
)

do {
    let activity = try await Activity<DeliveryAttributes>.request(
        attributes: attributes,
        content: ActivityContent(state: initialState, staleDate: nil),
        pushType: .token
    )
    print("Activity started: \(activity.id)")
} catch {
    print("Failed: \(error)")
}

SwiftUI View for Live Activity uses LockScreenView, ExpandedView and CompactView structures from WidgetKit. The View receives context (ActivityViewContext) with current attributes and state. View updates happen automatically when new state arrives from the system. Live Activity supports only a limited set of SwiftUI components — Text, Image, HStack, VStack and a few modifiers.

Each Live Activity View must be lightweight and fast — the system refuses to render heavy views. The rendering time limit is 30 ms per frame. Animations are limited to system transitions between states — custom animations in Live Activity are not available. Rendering is performed in a background WidgetKit process with Lock Screen responsiveness priority.

Updating Live Activity Locally and via Push

Local Update — the app updates Activity state by calling activity.update(using:). The method accepts a new ContentState and an optional AlertConfiguration for showing a notification on update. Local updates are fast — the system redraws the View on the next render cycle, typically within 1–2 seconds. For frequent updates (timer, stopwatch) use local mode — it is more reliable and faster than push.

swift
let updatedState = DeliveryAttributes.ContentState(
    status: DeliveryStatus.outForDelivery,
    estimatedMinutes: 10
)

await activity.update(
    ActivityContent<DeliveryAttributes.ContentState>(
        state: updatedState,
        staleDate: Date().addingTimeInterval(60)
    ),
    alertConfiguration: AlertConfiguration(
        title: "Order out for delivery",
        body: "Arriving in 10 min"
    )
)

Push Updates — the server sends an ActivityKit push notification with the new state in JSON format. For this, the app receives a pushToken from the activity.pushToken publisher and passes it to the server. The server sends a POST request to APNs with a payload containing the new ContentState. The system receives the push, decodes the state and updates the Live Activity without app involvement — this allows updating the Activity even when the app is closed.

Push updates are more efficient than local updates for infrequent updates (delivery status every 5–10 minutes) — the app does not need to maintain a network connection. For frequent updates every 1–2 seconds use the local method. The server payload includes only the mutable fields of ContentState — static Attributes data is sent only when creating the Activity.

Displaying Live Activity in Dynamic Island

Dynamic Island is a hardware-software area on iPhone 14 Pro, 15 Pro and newer that adapts to Live Activity content. The system automatically displays the Activity in three modes: compact (icon + short text to the left of the cutout), minimal (icon only) and expanded (300pt rectangle with information). The developer does not directly control these modes — the system selects the mode based on priority and available space.

swift
struct DeliveryLiveActivity: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: DeliveryAttributes.self) { context in
            LockScreenView(context: context)
        } dynamicIsland: { context in
            DynamicIsland {
                DynamicIslandExpandedContent {
                    ExpandedView(context: context)
                }
            } compactLeading: {
                CompactLeadingView(context: context)
            } compactTrailing: {
                CompactTrailingView(context: context)
            } minimal: {
                MinimalView(context: context)
            }
        }
    }
}

Dynamic Island supports interactivity — the user taps the area and enters the app or opens the expanded view. Tapping compact mode switches to expanded, and swiping left dismisses the Activity to minimal mode. Buttons in expanded mode (pause/cancel) are handled via Link from SwiftUI — the system launches the app with a deep link URL, processing is done in UIApplicationDelegate.

Dynamic Island Limitations: expanded mode width is up to 300pt, compact text is up to 30 characters. Colors and fonts match the system theme — customization is limited. Transition animations between modes are system-defined and cannot be customized. If multiple apps have active Activities, Dynamic Island displays them with priority based on launch time and content type.

Frequently Asked Questions

How is Live Activity different from a regular widget?

A regular WidgetKit widget displays static information and updates on a system timer with a minimum interval of 15–30 minutes. Live Activity shows dynamic data in real time on Lock Screen and Dynamic Island. Live Activity is launched by the app, lives up to 8 hours and is terminated by the system after the event ends, unlike a widget that exists permanently.

How often does Live Activity update?

Live Activity supports two update modes: local — the app updates state via ActivityKit API at any moment, and push update — the server sends an ActivityKit push notification which the system converts into a new widget state. When the battery is low, the system may freeze Live Activity until charging is connected.

Which devices support Live Activities?

Live Activities are available on iPhone with iOS 16.1 and newer. On iPhone 14 Pro and newer, Live Activity also displays in Dynamic Island. On iPad, Live Activity is supported only on Lock Screen — Dynamic Island is not available on iPad. Apple Watch does not support Live Activities directly, but can display completion notifications.

How many Live Activities can run simultaneously?

The system limits the number of active Live Activities — typically no more than 5 simultaneously for all apps. Attempting to start beyond the limit returns an error from ActivityKit. Each Live Activity can have multiple states — for example, pending, in transit, delivered for a food order. After completion, the Activity remains in UI for another 4 hours.

Is user permission required for Live Activity?

Yes, the app must request permission to send notifications — Live Activity uses the system notification channel. The user can disable Live Activity for a specific app in settings. On first launch, ActivityKit shows a dialog requesting permission. Without permission, the Activity request fails.

Summary

  • Live Activity — dynamic widget on Lock Screen and Dynamic Island with real-time updates
  • ActivityKit — iOS 16.1+ framework for managing Live Activity lifecycle
  • Attributes and State — static data and dynamic state of Activity passed to SwiftUI View
  • Push Updates — server sends new state via APNs without app involvement
  • Dynamic Island — three display modes: compact, minimal and expanded rectangle
  • Limits — up to 5 active Activities, up to 8 hours lifetime, up to 4 hours after completion
  • AlertConfiguration — optional notification when Activity state updates

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also