Mobile Development 13 min read

Implementing Dynamic Island (Live Activity) on iOS

This article explains the Dynamic Island UI feature introduced in iOS 16.1, detailing its API, placement, constraints, development workflow, ActivityAttributes, widget configuration, lifecycle management, deep linking, and suitable use cases, providing Swift code examples for developers to integrate Live Activities into iPhone apps.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Implementing Dynamic Island (Live Activity) on iOS

Overview

Dynamic Island (Dynamic Island) related APIs belong to the Live Activity framework that appears in iOS 16.1. Live Activities display an app's latest data on the iPhone Lock Screen and on the Dynamic Island, allowing users to see real‑time information at a glance and perform simple interactions.

Elements and Display Locations

Live Activity can present UI elements in two places:

iPhone Lock Screen page (requires iOS 16+)

Dynamic Island (requires iOS 16.1+ and iPhone 14 Pro / Pro Max)

System apps that currently support Dynamic Island include Ongoing Call, SharePlay, Music/Now Playing, Timer, Maps Directions, Voice Memos, Screen Recording, and Personal Hotspot.

Dynamic Island Screenshot Behavior

When the Dynamic Island has no active task, screenshots do not capture it; when a task is present, the island appears in the screenshot.

Requirements and Limitations

A Live Activity can stay active for up to 8 hours unless the app or the user ends it; after that the system automatically terminates it. When a Live Activity ends, it is removed from the Dynamic Island but remains on the Lock Screen until the user deletes it.

Each Live Activity runs in its own sandbox and cannot access the network or receive location updates. To update dynamic data, an app can use the ActivityKit framework or receive remote push notifications.

Implementation

Basic Flow

Note: Remote‑push updates require user authorization.

Development Framework & Configuration

Dynamic Island development depends on the new Live Activity framework as well as WidgetKit and SwiftUI. Your app must contain a widget extension target, create a WidgetBundle , and add a new ActivityWidget.

@main
struct HyWidget: WidgetBundle {
    var body: some Widget {
        HotWidget()
        UgcEntryWidget()
        // New Live Activity
        CoffeeDeliveryActivityWidget()
    }
}

The app’s Info.plist must include NSSupportsLiveActivities set to true .

ActivityAttributes

ActivityAttributes act as the data model, separating static data (attributes) from dynamic data (content state). The ContentState type represents the live, changing part of the activity.

struct CoffeeDeliveryAttributes: ActivityAttributes {
    public struct ContentState: Codable, Hashable {
        var currentStatus: CoffeeDeliveryStatus
    }
    var coffeeName: String
}

enum CoffeeDeliveryStatus: Codable, Sendable, CaseIterable {
    case recieved, preparing, outForDelivery
    var displayText: String {
        switch self {
        case .recieved: return "Recieved"
        case .preparing: return "Brewing"
        case .outForDelivery: return "On its way!"
        }
    }
    var longText: String {
        switch self {
        case .recieved: return "We've recieved your order."
        case .preparing: return "Our baristas are hard at work brewing up your cup!"
        case .outForDelivery: return "Get ready, your brew is speeding over to you right now."
        }
    }
}

Creating the ActivityWidget View

Dynamic Island supports three view styles from left to right: Compact, Minimal, and Expanded. The view can switch between these styles, and the expanded view appears when the user long‑presses the compact/minimal view or when the activity updates.

struct CoffeeDeliveryActivityWidget: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: CoffeeDeliveryAttributes.self) { context in
            CoffeeDeliveryActivityWidgetView(attributes: context.attributes, state: context.state)
        } dynamicIsland: { context in
            DynamicIsland {
                DynamicIslandExpandedRegion(.leading) {
                    // Expanded leading content
                }
                DynamicIslandExpandedRegion(.trailing) {
                    // Expanded trailing content
                }
            } compactLeading: {
                // Compact leading content
            } compactTrailing: {
                // Compact trailing content
            } minimal: {
                // Minimal content
            }
        }
    }
}

Lifecycle Management

Start

public static func request(attributes: Attributes, contentState: Activity
.ContentState, pushType: PushType? = nil) throws -> Activity

Example:

Task {
    let attributes = CoffeeDeliveryAttributes(coffeeName: coffeeName)
    let state = CoffeeDeliveryAttributes.ContentState(currentStatus: .recieved)
    do {
        let activity = try await Activity
.request(
            attributes: attributes,
            contentState: state,
            pushType: nil
        )
        print("Started activity")
    } catch {
        print("Error starting activity \(error)")
    }
}

Update

public func update(using contentState: Activity
.ContentState) async

Example:

func updateActivity(state: CoffeeDeliveryStatus) {
    let newState = CoffeeDeliveryAttributes.ContentState(currentStatus: state)
    Task {
        await liveActivity?.update(using: newState)
    }
}

Stop

func stop() {
    Task {
        await liveActivity?.end(using: nil, dismissalPolicy: .immediate)
        await MainActor.run { liveActivity = nil }
    }
}

Deep Link (Jump)

Dynamic Island supports deep links. Add the .widgetURL(_:) view modifier to the widget hierarchy. If multiple widgetURL modifiers exist, the behavior is undefined.

@ViewBuilder
var body: some View {
    ZStack {
        AvatarView(entry.character)
            .widgetURL(entry.character.url)
            .foregroundColor(.white)
    }
    .background(Color.gameBackground)
}

Applicable Scenarios (Preliminary)

Live Activities and Dynamic Island are suitable for apps that need to display frequently updated, short‑lived information that users monitor continuously, such as sports scores, fitness tracking, or food‑delivery status.

Sports event apps

Fitness monitoring apps

Food‑delivery apps

Summary

This article fully describes the development process for creating the Dynamic Island UI interaction, emphasizing the separation of static and dynamic data in the data model, the required frameworks, widget configuration, lifecycle handling, and deep‑linking. Apps that need to present timely status updates can benefit from integrating Dynamic Island to improve user experience.

References

Apple ActivityKit Documentation

Apple WidgetKit Documentation

iOSSwiftUIWidgetKitActivityKitDynamic IslandLive Activities
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.