0

I tried to use this method (see link attached) in a new Xcode 12 project as a way to create a login page for a SwiftUI app, but I had the Problem not knowing what to add to the main App struct. I'm still a beginner and tried adding ContentView().environmentObject(ViewRouter()) to the WindowGroup in the main app struct. Am I totally wrong or why doesn't Xcode build the view? Can somebody help? Below the working code snippet:

import SwiftUI
import Foundation
import Combine

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?


    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: MotherView().environmentObject(ViewRouter()))
            self.window = window
            window.makeKeyAndVisible()
        }
    }
. . .
}

class ViewRouter: ObservableObject {
    let objectWillChange = PassthroughSubject<ViewRouter,Never>()
    var currentPage: String = "page1" {
        didSet {
            withAnimation() {
                objectWillChange.send(self)
            }
        }
    }
}

struct MotherView : View {
    @EnvironmentObject var viewRouter: ViewRouter
    var body: some View {
        VStack {
            if viewRouter.currentPage == "page1" {
                ContentViewA()
            } else if viewRouter.currentPage == "page2" {
                ContentViewB()
                    .transition(.scale)
            }
        }
    }
}

struct ContentViewA : View {
    @EnvironmentObject var viewRouter: ViewRouter
    var body: some View {
        Button(action: {self.viewRouter.currentPage = "page2"}) {
            Text("Login")
        }
    }
}

struct ContentViewB : View {
    
    @EnvironmentObject var viewRouter: ViewRouter
    
    var body: some View {
        Button(action: {self.viewRouter.currentPage = "page1"}) {
            Text("Logout")
        }
    }
}

Now I want to substitute the SceneDelegate in the Xcode 12 style, but the following doesn't work. Any idea why?

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            MotherView().environmentObject(ViewRouter())
        }
    }
}

1 Answers1

0

Pls try next steps:

  1. remove whole SceneDelegate class (in your case no need SceneDelegate class)

  2. Modify your ViewRouter class like:

    class ViewRouter: ObservableObject { @Published var currentPage: String = "page1" }

Ernist Isabekov
  • 1,205
  • 13
  • 20
  • Thank you @ErnistIsabekov , I tried that now. It works on a real iPhone but not in Preview. There it always shows: `RemoteHumanReadableError: Failed to update preview. The preview process appears to have crashed. Error encountered when sending 'previewInstances' message to agent. ================================== | RemoteHumanReadableError: The operation couldn’t be completed. (BSServiceConnectionErrorDomain error 3.) | | BSServiceConnectionErrorDomain (3): | ==BSErrorCodeDescription: OperationFailed` – lennardkorte Sep 25 '20 at 11:04
  • Found a solution for the not working Preview: (https://stackoverflow.com/questions/57781982/how-to-set-an-environment-object-in-preview) Works perfectly fine now! – lennardkorte Sep 25 '20 at 11:16