Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI: where to put app initialization code so it doesn't run in preview?

Tags:

swiftui

I'm trying to find where to put app initialization code that should NOT be run in preview mode. I've seen several answers suggesting it's incorrect to split the app behaviour this way (launch vs preview), but I disagree: many apps need to do additional setup (eg connect to database, launch background tasks, call APIs, etc) that isn't appropriate for the preview (where static test data makes most sense).

In preview mode, Xcode actually runs the app and calls AppDelegate.applicationDidFinishLaunching, so any post-launch initialization code there will be triggered.

What is the recommended way to run app setup code so that it doesn't run in preview?

like image 826
Jacob Mouka Avatar asked Mar 09 '26 10:03

Jacob Mouka


2 Answers

It appears that Xcode sets an environment variable when running the app for SwiftUI previews. The key is "XCODE_RUNNING_FOR_PREVIEWS", which will have a value of "1".

Given this I found putting a guard statement that checks that environment value in my applicationDidFinishLaunching implementation before the initialization I didn't want to occur for previews fixed my preview (my initialization was making them fail entirely).

I also wrapped it in a DEBUG check to ensure it would not ever accidentally break a production build.

func applicationDidFinishLaunching(_ aNotification: Notification) {
    // Initialization needed for previews

    #if DEBUG
    guard ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] != "1" else {
        return
    }
    #endif

    // Further initialization not needed for previews
}
like image 164
Charles A. Avatar answered Mar 12 '26 03:03

Charles A.


The Preview Live, I assume you mean it, creates complete window scene context and injects there view to be previewed, so all application & scene delegate methods are called including instantiating root ContentView, but the root view is not shown, ie. its body is not called.

Thus you can achieve your goal by placing code, initiating all heavy/network/etc. operations in root view's .onAppear callback. And this, actually, will be good for your users as well, because such approach gives fast application start and initial UI presented.

like image 41
Asperi Avatar answered Mar 12 '26 02:03

Asperi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!