- Published on
- 3 min read
> How to Preview Live Activities in SwiftUI
- Authors

- Name
- Mick MacCallum
- @0x7fs
Building the UI for a Live Activity usually means a lot of back and forth: tweak the layout, build, start the activity, check the result, repeat. Xcode's #Preview macro cuts that loop short by letting you preview your Live Activity views right in the canvas, just like any other SwiftUI view.
The key is the as: parameter, which tells the preview what kind of Live Activity presentation to render. You can preview the expanded Dynamic Island, the compact views, the minimal view, or the Lock Screen content.
Setting Up a Preview
To preview a Live Activity, you need your ActivityAttributes type and at least one sample ContentState. Here's a complete example using a server monitoring activity:
import WidgetKit
import SwiftUI
struct ServerAttributes: ActivityAttributes {
var serverName: String
struct ContentState: Codable, Hashable {
var currentCpuUsage: Double
var currentMemoryUsage: Int
}
}
With your attributes defined, you can preview any presentation of the Dynamic Island. The #Preview macro accepts a display name, the presentation kind via as:, and the attributes instance via using:. You then provide one or more content states in the contentStates closure, which the preview canvas lets you cycle through:
import WidgetKit
import SwiftUI
#Preview("Expanded", as: .dynamicIsland(.expanded), using: ServerAttributes(serverName: "Preview Server")) {
ServerDetailsActivityConfiguration()
} contentStates: {
ServerAttributes.ContentState(currentCpuUsage: 0.752, currentMemoryUsage: 109232)
ServerAttributes.ContentState(currentCpuUsage: 0.681, currentMemoryUsage: 87563)
}
This renders the expanded Dynamic Island view right in the Xcode canvas. You can provide multiple content states to see how your layout handles different data without restarting the activity each time.
Dynamic Island Presentation Kinds
The dynamicIsland(_:) method accepts a DynamicIslandPreviewViewState that controls which presentation you see. There are four options:
.expanded renders the full expanded view that users see when they long-press the Dynamic Island.
.compactLeading and .compactTrailing show the compact views that appear side by side when your app is the only one running a Live Activity.
.minimal shows the small circular view used when multiple Live Activities are running at the same time.
import WidgetKit
import SwiftUI
#Preview("Compact Leading", as: .dynamicIsland(.compactLeading), using: ServerAttributes(serverName: "Web-01")) {
ServerDetailsActivityConfiguration()
} contentStates: {
ServerAttributes.ContentState(currentCpuUsage: 0.45, currentMemoryUsage: 62000)
}
#Preview("Minimal", as: .dynamicIsland(.minimal), using: ServerAttributes(serverName: "Web-01")) {
ServerDetailsActivityConfiguration()
} contentStates: {
ServerAttributes.ContentState(currentCpuUsage: 0.92, currentMemoryUsage: 120000)
}
Previewing the Lock Screen Content
Live Activities also appear on the Lock Screen. To preview that presentation, use .content instead of .dynamicIsland:
import WidgetKit
import SwiftUI
#Preview("Lock Screen", as: .content, using: ServerAttributes(serverName: "Production DB")) {
ServerDetailsActivityConfiguration()
} contentStates: {
ServerAttributes.ContentState(currentCpuUsage: 0.33, currentMemoryUsage: 45000)
}
This is especially useful since the Lock Screen layout has more room than the Dynamic Island and often needs its own design attention.
Tips for Effective Previews
Providing multiple content states is the biggest time saver. Think about edge cases: what happens when a value is at 0% versus 100%? What about long strings that might clip? Each state you add to the contentStates closure becomes a separate preview you can flip through in the canvas.
If your preview isn't rendering, make sure the file is part of your widget extension target, not the main app target. The #Preview macro for Live Activities needs access to your ActivityConfiguration, which lives in the widget extension.
For the full API reference, see Apple's documentation on Preview(_:as:using:widget:contentStates:).
// Continue_Learning
Debugging SwiftUI Previews in Xcode
When SwiftUI previews break, the error messages aren't always helpful. Here's how to debug them, clear caches, and get back to a working state.
Fixing SwiftUI Previews That Won't Load
When SwiftUI previews fail with cryptic errors or just spin forever, here's how to diagnose and fix the most common causes.
Previewing Partially Generated Content with Foundation Models in SwiftUI
When building UIs that stream AI-generated content using Apple's Foundation Models framework, testing intermediate states in Xcode Previews requires some creative workarounds. Here's how to preview partially generated content without calling the actual model.
// Stay Updated
Get notified when I publish new tutorials on Swift, SwiftUI, and iOS development. No spam, unsubscribe anytime.