Is it possible to migrate an old Xcode project to use SwiftUI?

后端 未结 3 1056
梦如初夏
梦如初夏 2020-12-08 21:11

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

相关标签:
3条回答
  • 2020-12-08 21:36

    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

    0 讨论(0)
  • 2020-12-08 21:39

    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.

    0 讨论(0)
  • 2020-12-08 21:57

    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.

    0 讨论(0)
提交回复
热议问题