NavigationStack crashes when changing path in iOS 17.1.2

68 views Asked by At

In my SwiftUI app I'm using NavigationStack with navigationDestination modifier to navigate user between views. In my AppState I'm holding a state for array of NavigationPath that are triggering state in my ContentView with Combine's Publisher:

struct NavigationState: Equatable {
    var path: [NavigationPath] = []
}
    
enum NavigationPath: Hashable {
    case view1
    case view2
    case view3
    case view4
}

To navigate between views I have a NavigationState extension. These are the methods I call on appState to change path array:

extension AppState.NavigationState {
    mutating func navigate(to destination: AppState.NavigationPath) {
        if !path.contains(destination) {
            path.append(destination)
        }
    }
    
    mutating func pop() {
        _ = path.popLast()
    }
    
    mutating func popToView2() {
        path = [.view2]
    }
}

This is how the ContentView looks like:

struct ContentView: View {
    @State private var navigationPath: [AppState.NavigationPath] = [.view1]
    
    var body: some View {
            NavigationStack(path: $navigationPath) {
                View1()
                    .navigationDestination(for: AppState.NavigationPath.self) { path in
                        switch path {
                        case .view1:
                            View1()
                        case .view2:
                            View2()
                        case .view3:
                            View3()
                        case .view4:
                            View4()
                        }
                    }
            }
            .onReceive(navigationPathUpdate) {
                self.navigationPath = $0
            }
    }
}

// MARK: - State Update

private extension ContentView {
    var navigationPathUpdate: AnyPublisher<[AppState.NavigationPath], Never> {
        container.appState.updates(for: \.navigationState.path)
    }
}

updates method is just for updating the state and I guess it's not important to explain in detail.

In the end the code works perfect on all iPhones and in all iOS versions except iOS 17.1.2 (tester's iPhone 14 Pro). When the user calls popToView2 app crashes. I've tried to comment out this call and in that case app is not crashing for the tester, so the only guess left is that popToView2 does something bad. I have a crash log in Xcode but it doesn't point the exact line of code where the problem is. popToView2 is used after log out to show login screen again.

Crash log in Xcode

Did anyone experience something similar?

1

There are 1 answers

0
malhal On

You are supposed to use multiple navigationDestination modifiers for each type of value, not a single modifier with an enum/switch inside. These are designed to be declared throughout your View (model) struct hierarchy. The path has been specially designed to be able to hold different types unlike array.