UIKit apps and SwiftUI apps have a completely different internal structure in Xcode. Building on Sam Khawase’s great guide, here is how I have converted my apps from UIKit to SwiftUI. My conversion is done in one step, instead of progressing through a series of steps where the app is a hybrid of UIKit and SwiftUI.

1. Set the iOS Deployment Target to be 14.1 or higher for both the project and the targets.

2. Create a new app class. Go to File ... New File (iOS, Swift File), and choose a name like CoolApp.swift, replacing Cool with the name of the app.

Replace the contents of that file with the following, which is what Xcode uses when you create an empty SwiftUI app. Change the struct name to CoolApp, again replacing it with the name of your app

import SwiftUI
struct AppnameApp: App {
  var body: some Scene {
    WindowGroup {

Ignore the warning about not finding ContentView() in scope, as that will be fixed next.

2. Create a new ContentView() class. Go to File...New File (iOS, SwiftUI View File), and name the file ContentView, to match what is the app class you just created. This file will be pre-populated with Xcode’s boilerplate code, which is fine for now. Previews will become available in the next step.

3. Disable the AppDelegate class you have from the UIKit version by removing @UIApplicationMain from the top of that file. You can build and run at this point, and you should see a screen with the default “Hello, World!’ text in black in the center of an all-white screen.

4. Modify the info.plist file. First, delete the entry for Main storyboard file base name if you have one. Second, add an entry for Application Scene Manifest. Open that and set the value to YES for Enable Multiple Windows.

5. Create a basic blank launch screen. First, go to the .xcassets file, create a new Color Set, and name it launchScreenBackground. Adjust the Any Appearance and Dark Appearance colors to whatever matches your app. Second, in info.plist, delete the entry for Launch screen interface file base name, if you have one. Last, at the root level of info.plist, add a row called Launch Screen. From within it, add Background color, and set it to launchScreenBackground. If you build and run at this point, you should see the same as before, but with your new launch screen (just a solid color for now).

6. Update your targets. For the app target, go to Build Phases. Under compile sources, remove any sources that will no longer be used (app delegate, view controllers, views), but keep any model objects. If you wish, you can delete these same files in the Navigator Area (left-most column of Xcode) right now, or you can delete them later, keeping them for now if you want to refer to them as you migrate the functionality of your app to SwiftUI. Do the same under Build Phases ... Copy Bundle Resources, deleting the Main.storyboard and the Launch Screen.storyboard (if you have these), and similar storyboards that won't be needed. Again, you can delete them now in the Navigator, or you can delete them later when you no longer wish to refer to them.

Repeat these two steps (cleaning out Compile Sources and Copy Bundle Resources) for the test target.

7. Remove Derived Data. Go to ~/Library/Developer/Xcode/DerivedData and delete the folder for the app.

That’s it! If you build and run, everything should build without errors and warnings. Now you can begin adding SwiftUI views, view models, etc. to convert the functionality of your app to SwiftUI. Note that some of your tests may no longer work depending on what you have removed, so you may need to replace some of your tests.