Reputation: 578
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 already tried to add the UIApplicationSceneManifest
key in Info.plist
, I changed the AppDelegate.swift
to use scenes, I created the SceneDelegate.swift
and even then I could not
Upvotes: 25
Views: 13596
Reputation: 2378
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
Upvotes: 8
Reputation: 22846
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.
Upvotes: 32
Reputation: 21883
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.
Upvotes: 4