Introduction

SwiftUI previews use PreviewDevice to simulate specific Apple device configurations. When an invalid or unavailable device name is specified, the preview fails to render with an error about the device not being found. This commonly happens after Xcode updates that change device names, when simulator runtimes are not installed, or when using custom device configurations that do not exist in the current Xcode installation.

Symptoms

  • Xcode preview shows PreviewDevice not found error
  • .previewDevice(PreviewDevice(rawValue: "iPhone 15")) fails
  • Preview renders as generic device instead of specified model
  • Simulator runtime not installed for target device
  • Device name typo causes silent fallback to default preview

Error in preview canvas: `` Failed to update preview. The preview process appears to have crashed. Error encountered when sending 'prepare' message to the agent.

Common Causes

  • Device name string does not match available simulator devices exactly
  • Simulator runtime not downloaded for the target iOS version
  • Xcode update changed device naming convention
  • Using device name from older Xcode version
  • Typo or extra whitespace in device name string

Step-by-Step Fix

  1. 1.**List all available preview devices":
  2. 2.```bash
  3. 3.# In terminal, list all available simulator devices
  4. 4.xcrun simctl list devices available

# Example output: # == Devices == # -- iOS 17.4 -- # iPhone 15 (A1B2C3D4-...) (Booted) # iPhone 15 Pro (E5F6G7H8-...) (Shutdown) # iPad Pro 13-inch (M9N0O1P2-...) (Shutdown)

# These exact names are what PreviewDevice expects ```

  1. 1.**Use correct device names in preview configuration":
  2. 2.```swift
  3. 3.import SwiftUI

struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() // Use EXACT names from xcrun simctl list .previewDevice(PreviewDevice(rawValue: "iPhone 15")) .previewDisplayName("iPhone 15")

ContentView() .previewDevice(PreviewDevice(rawValue: "iPhone 15 Pro Max")) .previewDisplayName("iPhone 15 Pro Max")

ContentView() .previewDevice(PreviewDevice(rawValue: "iPad Pro 13-inch (M4)")) .previewDisplayName("iPad Pro 13") } }

// Common valid device names (verify with xcrun simctl): // "iPhone 15", "iPhone 15 Plus", "iPhone 15 Pro", "iPhone 15 Pro Max" // "iPhone SE (3rd generation)" // "iPad Pro 11-inch (M4)", "iPad Pro 13-inch (M4)" // "iPad Air 13-inch (M2)" // "iPad mini (A17 Pro)" ```

  1. 1.**Install missing simulator runtime":
  2. 2.```bash
  3. 3.# List available runtimes
  4. 4.xcrun simctl list runtimes

# If iOS runtime is missing, download it: # 1. Open Xcode > Settings > Platforms # 2. Find the iOS version you need # 3. Click Download

# Or via command line (Xcode 15+): xcodebuild -downloadAllPlatforms

# After installation, restart Xcode ```

  1. 1.**Use previewLayout as an alternative to previewDevice":
  2. 2.```swift
  3. 3.struct ContentView_Previews: PreviewProvider {
  4. 4.static var previews: some View {
  5. 5.// Phone-sized preview without needing specific device
  6. 6.ContentView()
  7. 7..previewLayout(.fixed(width: 393, height: 852))
  8. 8..previewDisplayName("iPhone-sized")

// Dynamic type size preview ForEach(ContentSizeCategory.allCases, id: \.self) { size in ContentView() .environment(\.sizeCategory, size) .previewLayout(.sizeThatFits) .previewDisplayName(size.rawValue) }

// Dark mode preview ContentView() .preferredColorScheme(.dark) .previewLayout(.sizeThatFits) .previewDisplayName("Dark Mode") } } ```

Prevention

  • Use xcrun simctl list devices available to get exact device names
  • Avoid hardcoding device names; use constants or an enum
  • Install required simulator runtimes as part of project setup
  • Use previewLayout(.fixed) for dimension-specific testing
  • Add a CI check that verifies preview configurations
  • Document minimum Xcode version and required simulator runtimes