rundfunk47 / stinsen

Coordinators in SwiftUI. Simple, powerful and elegant.
MIT License
926 stars 98 forks source link

TabCoordinatable does not deinit when parent coordinator changes its root #136

Closed sbilling closed 3 months ago

sbilling commented 3 months ago

This behavior can be observed in the example app. The logout button on the profile screen calls:

AuthenticationService.shared.status = .unauthenticated

which trips the observation in the maincoordinator:

@ViewBuilder func sharedView(_ view: AnyView) -> some View {
        view
            .onReceive(AuthenticationService.shared.$status, perform: { status in
                switch status {
                case .unauthenticated:
                    self.root(\.unauthenticated)
                case .authenticated(let user):
                    self.root(\.authenticated, user)
                }
            })

    }

However, on switching the root, the AuthenticatedCoordinator does not deinit and neither do any of its children.

Furthermore, it appears as if Stinsen attempts to redraw the TabCoordinatable as the root is switched. This causes odd behavior like task and onAppear closures being called on the views that were brought into the view hierarchy. To reproduce do the following:

  1. Add a task like so to the TodosScreen

    @ViewBuilder var content: some View {
        ScrollView {
            #if !os(iOS)
            button
            #endif
            if todosStore.all.isEmpty {
                InfoText("You have no stored todos.")
            }
            VStack {
                ForEach(todosStore.all) { todo in
                    Button(todo.name, action: {
                        todosRouter.route(to: \.todo, todo.id)
                    })
                }
            }
            .padding(18)
        }
        .navigationTitle(with: "Todos")
        .task {
            print("here at the wall")
        }
    }
  2. Launch the app

  3. Tap "Login" and then navigate to the Todos tab. Note: you will see here at the wall printed in Xcode console.

  4. Navigate to the profile tab and tap "logout"

  5. Observe: "here at the wall" is printed again after the root has been switched to unauthenticated

sbilling commented 3 months ago

turns out this might not have anything to do with Stinsen https://developer.apple.com/forums/thread/719521?login=true and https://forums.developer.apple.com/forums/thread/718738