Check if a SwiftUI View is in Preview

SwiftUI Preview is a fantastic piece of development tooling to quickly iterate UI designs in Xcode. But sometimes the code in your view just doesn't work--or worse it crashes the preview engine.  How can we work around this issue?

I ran into a Preview crash issue in a SwiftUI view containing a Sign in with Apple button.

Simulator is no problem

When running on a simulator, the view rendered correctly, but when Preview resumed with the SIWA button in the view hierarchy, Preview crashed:

[App Name] quit unexpectedly.
Click Reopen to open the application agani. This report will be sent automatically to Apple.

Substitute different code for Xcode Preview

My first reaction was to wonder if In these cases it can be handy to render some type of placeholder UI in Preview mode, and render the real UI when running on a simulator or physical device.  After some searching, I found the following approach:

if ProcessInfo
        .environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" {
    // Render a plain SwiftUI View when in preview
    Button("Sign in with Apple Button Here") {
        print("Sign in with apple pressed")
    }.standardButton(buttonColor: Color(.black))
} else {
    // Render the actual SIWA button when running on Sim or Device
           onRequest: configureAppleSignInButton,
           onCompletion: sessionManager.handleAppleSignIn)
            colorScheme == .dark ? .white : .black
        .frame(height: 50)
        .padding([.top], 10)

In the code above, the the Xcode environment variable XCODE_RUNNING_FOR_PREVIEWS is used to let the SwiftUI view know that it should render something simple that will not crash the preview pane.  I used a standard SwiftUI button (with some custom styling, but it's just a normal button).

View now working in Preview

The result of adding the Preview detection if/else statement is the following. The styling is such that the size and placement of the button will reflect the "real" SIWA button. This allows us to continue the screen layout in the preview pane rather than needing to run the app in a simulator window on each layout change.

View now working correctly in Preview with "for position only" Button