What Are iOS Live Activities?
Live Activities are persistent, glanceable widgets that appear on the iPhone Lock Screen and Dynamic Island, displaying real-time updates for ongoing events. Unlike traditional push notifications that appear briefly and then disappear into Notification Center, Live Activities remain visible for the duration of an activity, providing continuous visibility into events as they unfold.
When you look at your Lock Screen, Live Activities appear as persistent cards that stay pinned at the top, updating in real-time as the underlying event progresses. On iPhones with Dynamic Island, activities can also appear in the small space at the top of the screen, expanding when you tap on them to show more details. This persistent nature eliminates the need to unlock your phone, open an app, or navigate through multiple screens just to check on an ongoing event.
For mobile app developers, Live Activities represent a powerful tool for keeping users engaged without the friction of traditional notifications. The average smartphone user receives approximately 46 push notifications per day, contributing to notification fatigue and reduced engagement with important updates. Live Activities address this problem by consolidating multiple status updates into a single, glanceable surface that users can check whenever they pick up their device, without contributing to notification overload.
Key Statistics:
- Users can check Live Activities at a glance without unlocking their device
- Live Activities remain visible for the duration of an event (up to 8 hours)
- Compatible with iOS 16 and later on all iPhones, Dynamic Island on iPhone 14 Pro and later
- Activities automatically sync to Apple Watch via watchOS 11 Smart Stack
Key benefits for developers and users
Persistent Visibility
Live Activities remain on the Lock Screen for the duration of an event, providing continuous visibility without repeated notifications.
Dynamic Island Integration
Activities appear in the Dynamic Island on supported iPhones, allowing users to monitor progress even while using other apps.
Cross-Device Sync
With iOS 18 and watchOS 11, Live Activities automatically appear in the Apple Watch Smart Stack for wrist-based monitoring.
Reduced Notification Fatigue
Consolidating updates into a single Live Activity reduces the notification burden on users while keeping them informed.
Technical Architecture: ActivityKit and WidgetKit
The Live Activities API is built on two complementary frameworks that work together to create complete real-time experiences. Understanding how these frameworks interact is essential for building effective Live Activities, whether you're building a native iOS app or working with a web development team that specializes in mobile integrations.
ActivityKit
ActivityKit handles the entire lifecycle management of Live Activities, providing the core functionality for starting, updating, and ending activities. This framework is responsible for:
- Requesting Activities: Starting new Live Activities with user-defined attributes
- Updating Content: Modifying the activity state while it remains active
- Managing State: Handling activity states like active, ended, or dismissed
- Push Updates: Receiving updates via push notifications when the app isn't running
When you request a Live Activity, ActivityKit returns an Activity object that you use to manage the activity's lifecycle. This object provides methods for updating content and ending the activity, as well as observing state changes.
WidgetKit
WidgetKit provides the rendering layer that determines how activities appear across different system surfaces. Rather than using standard UIKit or SwiftUI views, Live Activities use WidgetKit's activity-specific configuration to render their interface:
- Lock Screen View: The full widget experience visible when viewing the Lock Screen
- Dynamic Island Compact: Minimal view showing essential information in the collapsed Dynamic Island
- Dynamic Island Expanded: Larger view when users interact with or long-press the Dynamic Island
- StandBy Mode: Information display when iPhone is charging and positioned sideways on a dock
How They Work Together
Both frameworks work in concert--ActivityKit manages the data and lifecycle while WidgetKit renders the appropriate UI for each surface based on the current content state. When an activity's content state changes (either through direct updates or push notifications), WidgetKit automatically refreshes the displayed widgets across all surfaces where the activity appears.
Step 1: Defining Activity Attributes
Every Live Activity requires a structured data model that separates static attributes from dynamic content state. The ActivityAttributes struct defines both types of data, and this separation is crucial for efficient updates.
Static Attributes remain constant throughout the activity's lifetime--for example, an order ID, restaurant name, or participant names. These values are set when the activity begins and never change. By marking attributes as static, the system can optimize how data is stored and transmitted.
Content State (also called dynamic state) changes as the activity progresses--delivery status updates, driver location, progress percentage, or score changes. This state is transmitted to WidgetKit for UI updates and is designed to be lightweight for efficient real-time updates.
Both the attributes and content state must conform to Codable to support persistence and transmission through the ActivityKit system. The ContentState is particularly important because it's what triggers UI updates when changes occur.
1struct DeliveryAttributes: ActivityAttributes {2 let orderId: String3 let restaurantName: String4 let estimatedDeliveryTime: Date5 6 public struct ContentState: Codable, Hashable {7 var status: DeliveryStatus8 var driverName: String?9 var driverDistance: Double? // in miles10 var progressPercentage: Int // 0-10011 }12}13 14enum DeliveryStatus: String, Codable, Hashable {15 case confirmed16 case preparing17 case readyForPickup18 case pickedUp19 case onTheWay20 case arrived21 case delivered22 23 var displayText: String {24 switch self {25 case .confirmed: return "Order Confirmed"26 case .preparing: return "Preparing Your Order"27 case .readyForPickup: return "Ready for Pickup"28 case .pickedUp: return "Driver Picked Up Order"29 case .onTheWay: return "On The Way"30 case .arrived: return "Driver Has Arrived"31 case .delivered: return "Delivered"32 }33 }34}Step 2: Creating the Live Activity Widget
The widget configuration defines how Live Activities appear across different system surfaces using ActivityConfiguration. According to Apple's Human Interface Guidelines, you specify layouts for each display context to ensure optimal presentation everywhere.
The Lock Screen view provides the most space and should contain the complete information hierarchy. The Dynamic Island has multiple states--compact, expanded, and minimal--each designed for different interaction levels and information density. You use DynamicIsland to configure how your activity appears in each of these states.
For the compact representation in the Dynamic Island, you define content for the leading and trailing edges. The expanded region provides more space when users interact with the activity, and the minimal view shows only essential information when space is constrained.
Using SF Symbols ensures consistent rendering across all device configurations and Dynamic Island sizes. The activityBackgroundTint modifier provides visual integration with the Lock Screen's aesthetic.
1import WidgetKit2import SwiftUI3import ActivityKit4 5struct DeliveryActivityWidget: Widget {6 var body: some WidgetConfiguration {7 ActivityConfiguration(for: DeliveryAttributes.self) { context in8 // Lock Screen View9 VStack(alignment: .leading, spacing: 12) {10 HStack {11 Image(systemName: "takeoutbag.and.cup.and.straw.fill")12 .font(.title2)13 Text(context.attributes.restaurantName)14 .font(.headline)15 }16 17 Text(context.state.status.displayText)18 .font(.title3)19 .fontWeight(.semibold)20 21 ProgressView(value: Double(context.state.progressPercentage), total: 100)22 .tint(.green)23 24 if let driverName = context.state.driverName {25 HStack {26 Image(systemName: "person.circle.fill")27 Text(driverName)28 }29 .font(.subheadline)30 .foregroundStyle(.secondary)31 }32 }33 .padding()34 .activityBackgroundTint(.ultraThinMaterial)35 } dynamicIsland: { context in36 DynamicIsland {37 DynamicIslandExpandedRegion(.leading) {38 Image(systemName: "takeoutbag.and.cup.and.straw.fill")39 }40 DynamicIslandExpandedRegion(.trailing) {41 Text("\(context.state.progressPercentage)%")42 .font(.caption)43 .fontWeight(.bold)44 }45 DynamicIslandExpandedRegion(.bottom) {46 VStack(alignment: .leading, spacing: 4) {47 Text(context.state.status.displayText)48 .font(.caption)49 .fontWeight(.medium)50 if let driver = context.state.driverName {51 Text(driver)52 .font(.caption2)53 .foregroundStyle(.secondary)54 }55 }56 }57 } compactLeading: {58 Image(systemName: "takeoutbag.and.cup.and.straw.fill")59 } compactTrailing: {60 Text("\(context.state.progressPercentage)%")61 .font(.caption2)62 .fontWeight(.bold)63 } minimal: {64 ProgressView()65 }66 }67 }68}Step 3: Starting and Updating Activities
Live Activities must be explicitly requested from the app following a user-initiated action. This design ensures activities only begin when users intentionally engage with a real-time event, preventing unauthorized tracking or battery drain from background activities.
Starting an Activity
The Activity.request method creates a new Live Activity and returns an Activity object that you use for subsequent lifecycle management. You provide both the static attributes and the initial content state. The system validates the request and returns an activity or throws an error if the request fails--common reasons include the user having disabled Live Activities globally or the app exceeding its activity limit.
Updating Content
The Activity.update method modifies the content state, triggering WidgetKit to refresh the displayed widgets. For activities that should continue updating when the app isn't running, you can also configure push notification support, allowing remote servers to send updates through Apple's push infrastructure.
Ending Activities
When an event concludes, Activity.end properly terminates the activity. The optional dismissal policy determines how long the activity remains visible after ending--immediate dismissal, dismissal after a time interval, or persistence until the user manually dismisses it. Always provide appropriate ending behavior to maintain user trust.
1// MARK: - Starting a Live Activity2func startDeliveryActivity(orderId: String, restaurant: String, eta: Date) {3 let attributes = DeliveryAttributes(4 orderId: orderId,5 restaurantName: restaurant,6 estimatedDeliveryTime: eta7 )8 let initialState = DeliveryAttributes.ContentState(9 status: .confirmed,10 driverName: nil,11 driverDistance: nil,12 progressPercentage: 013 )14 15 Task {16 do {17 let activity = try Activity.request(18 attributes: attributes,19 contentState: initialState20 )21 print("Live Activity started: \(activity.id)")22 } catch {23 print("Failed to start activity: \(error)")24 }25 }26}27 28// MARK: - Updating Activity Content29@MainActor30func updateDeliveryProgress(activity: Activity<DeliveryAttributes>, 31 status: DeliveryStatus, 32 driver: String?,33 distance: Double?,34 progress: Int) {35 let updatedState = DeliveryAttributes.ContentState(36 status: status,37 driverName: driver,38 driverDistance: distance,39 progressPercentage: progress40 )41 await activity.update(using: updatedState)42}43 44// MARK: - Ending an Activity45func completeDelivery(activity: Activity<DeliveryAttributes>) {46 let finalState = DeliveryAttributes.ContentState(47 status: .delivered,48 driverName: nil,49 driverDistance: nil,50 progressPercentage: 10051 )52 53 Task {54 await activity.end(nil, dismissalPolicy: .after(Date().addingTimeInterval(3600)))55 }56}iOS 18 Changes and Update Frequency
Apple introduced significant changes to Live Activities in iOS 18, particularly around update frequency. According to Apple's ActivityKit announcements, understanding these limitations is crucial for planning your implementation strategy.
Update Frequency Throttling
Starting with iOS 18, Apple throttles Live Activity updates to intervals between 5-15 seconds. This reflects Apple's philosophy that Live Activities were never designed for sub-second real-time updates. The exact interval is determined by the system based on device conditions and user behavior patterns.
Significantly Affected Use Cases:
- Fitness tracking with high-frequency pace updates
- Stock price tickers requiring near-real-time updates
- Live sports play-by-play with second-by-second commentary
Unaffected or Minimally Affected Use Cases:
- Delivery tracking (naturally exceeds 5-second intervals between status changes)
- Ride-sharing ETAs (countdown timers run locally without server updates)
- Flight status updates (typically minutes between changes)
- Package tracking (sparse update requirements)
The 5-15 second interval represents a minimum floor--your activity won't update more frequently than this, but many real-world use cases naturally operate on longer timescales already.
Apple Watch Integration
iOS 18 extends Live Activities to Apple Watch through watchOS 11's Smart Stack. iPhone Live Activities automatically appear on compatible wearables, providing cross-device consistency for users who prefer to monitor activities on their wrist. This integration requires no additional code beyond standard Live Activity implementation and demonstrates Apple's commitment to seamless iOS development across their ecosystem.
Design Considerations for Apple Watch:
- Prioritize the most essential metrics for the smaller watch display
- Ensure fonts remain readable at typical watch viewing distances
- Consider how information hierarchies translate to wrist-based viewing
- Test battery impact when activities run continuously on Apple Watch
Efficient Update Strategies
- Batch Updates: Combine multiple changes into single updates rather than sending incremental changes. Each update has overhead, so consolidating changes reduces system load.
- Respect Frequency Limits: Don't attempt to update more frequently than iOS 18's 5-15 second minimum. The system will throttle your updates anyway, but attempting frequent updates wastes resources.
- Use Local Timers: For countdown-based updates like ETAs, run timers locally on the device instead of requesting server updates for every tick. This reduces network traffic and server costs.
Size and Resource Constraints
- Keep UI Simple: Lock Screen and Dynamic Island layouts have strict size constraints. Large images may be clipped or scaled unpredictably.
- Use SF Symbols: System icons render reliably across all device configurations and Dynamic Island sizes, ensuring consistent appearance.
- Minimize Complexity: Excessive widget complexity impacts both performance (battery life, rendering time) and readability (harder to parse at a glance).
Security and Privacy
According to Apple's guidelines, Live Activities appear on the Lock Screen, making privacy paramount:
- Never Display Sensitive Data: Personal messages, financial information, health metrics, or other private data should not appear in Live Activities.
- Surface General Status: Show high-level progress while routing sensitive details to the app when users need more information.
- Provide Clear Descriptions: Users should understand what information appears in their Live Activities.
Testing Across Devices
- Dynamic Island: Available exclusively on iPhone 14 Pro, iPhone 14 Pro Max, iPhone 15 Pro, iPhone 15 Pro Max, and later models.
- Non-Pro iPhones: Support Lock Screen Live Activities but lack Dynamic Island integration.
- Test All States: Verify appearance in compact, expanded, and minimal Dynamic Island states to ensure information hierarchy works at all sizes.
- StandBy Mode: Test how your activity appears when iPhone is charging and in landscape orientation.
Real-World Use Cases
Live Activities have found adoption across numerous industries, each leveraging the technology to address specific user needs. As noted in comprehensive implementation guides, the key is identifying events where continuous visibility adds genuine value. For businesses investing in custom web and mobile applications, Live Activities represent an opportunity to differentiate their apps through superior user experience.
Food Delivery and Restaurant Apps
Food delivery platforms use Live Activities to show order status from preparation through delivery, eliminating the need for users to repeatedly open the app or receive multiple status notifications. Users can simply glance at their Lock Screen to see whether their order is being prepared, picked up, or approaching.
Implementation Tips:
- Use progress percentage to show overall completion clearly
- Display restaurant name prominently for quick identification
- Include driver information when the order is picked up
- Show estimated time remaining when available
Ride-Sharing and Transportation
Ride-hailing apps leverage Live Activities to display driver location and ETA information, giving users real-time visibility into their ride's approach without unlocking their phone. This reduces anxiety during waits and helps users time their departure accordingly.
Implementation Tips:
- Use countdown timers that run locally for ETA (doesn't require server updates)
- Show driver name and vehicle information for identification
- Include distance to arrival in clear units
- Update status as the ride progresses through stages
Fitness and Health Applications
Workout and fitness apps use Live Activities to surface key metrics during exercise, allowing users to check progress without breaking their workout flow to unlock their phone and navigate through apps.
Implementation Tips:
- Prioritize the most important metrics for your specific activity type
- Consider iOS 18 update frequency limitations for truly high-frequency data
- Use large, readable fonts visible at a glance during movement
- Include progress indicators for workout duration or distance goals
Travel and Airline Applications
Flight tracking apps use Live Activities to display gate changes, delay notifications, and boarding status, helping travelers stay informed without constantly checking airport displays or their airline app.
Implementation Tips:
- Surface critical information like gate numbers prominently in large text
- Show flight status at a glance (on time, delayed, boarding)
- Include departure and arrival times
- Highlight changes (especially gate changes) with visual emphasis
Frequently Asked Questions
Conclusion
The iOS Live Activities API represents a significant opportunity for developers to create engaging, real-time experiences that integrate seamlessly with iOS system surfaces. By understanding the technical foundations through ActivityKit and WidgetKit, respecting iOS 18's updated constraints around update frequency, and following established best practices for performance and privacy, you can build Live Activities that genuinely enhance user engagement without contributing to notification fatigue.
The technology excels in scenarios where users need ongoing visibility into real-time events--delivery tracking, ride-sharing, fitness progress, and travel updates--making it a valuable addition to any app that manages time-sensitive information. The key is identifying events where continuous, glanceable updates provide genuine value rather than merely replicating push notification functionality.
As Apple continues to expand Live Activities capabilities across devices including Apple Watch through Smart Stack integration, the opportunity for meaningful real-time user experiences only grows. Start by identifying the real-time events most important to your users, then design Live Activities that provide continuous, glanceable updates that respect both user attention and device resources.
Related Resources:
- Learn more about our mobile app development services
- Explore our iOS development expertise
- Discover our web development capabilities
Ready to implement Live Activities in your app? Our team specializes in building real-time iOS experiences that keep users engaged and informed. Contact us to discuss your project requirements.