I have an app made in Xcode 10 using Main.storyboard and would like to migrate it to use Apple\'s new framework: SwiftUI.
Is that already possible?
I have alrea
It's a correct only minor change
In SceneDelegate.swift replace
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = UIHostingController(rootView: ContentView())
self.window = window
window.makeKeyAndVisible()
with
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: ContentView())
self.window = window
window.makeKeyAndVisible()
}
TAKEN FROM HERE
My solution turned out to be different. In my case, I had everything in place, but when the code attempted to load the UISceneConfiguration, it failed to load the config in the Info.plist and gave me a secondary window config instead with no scene delegate set. If I asked for the correct configuration from the debug console it would load as expected. I was confused.
I double checked everything and tried all of the suggestions here but none worked. In the end I did 'Hardware' - 'Erase all contents and settings...' on the simulator and that solved it.
My guess is that because I'd been running the pre-SwiftUI version of the app on the simulator, something in that caused the SwiftUI version to behave differently.
I assume you're using Xcode 11 GM and macOS Mojave or Catalina.
Along with the changes in the plist, you have to add UISceneSession lifecycle functions in the application delegate.
func application(_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// The name must match the one in the Info.plist
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
}
Also, you need to make sure the window is created correctly in the SceneDelegate.
func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else {
return
}
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: ContentView())
self.window = window
window.makeKeyAndVisible()
}
where ContentView is the main SwiftUI view you want to display.
P.S. Make sure the plist specifies $(PRODUCT_MODULE_NAME).SceneDelegate as delegate class name, and the scene delegate is called SceneDelegate
Example:
If you're on Catalina, you can turn on Previews in the build settings for your target.
Build Options -> Enable Previews
Addendum I:
Make sure you remove the Storyboard key from the Info.Plist and that you're targeting iOS 13.
Addendum II:
Clean Derived Data, as many devs in the comments suggest.