I am trying to recreate the account followers flow seen in many social media apps in SwiftUI.
- You press a button on your profile to see a list of your followers
- You can click on any one of your followers to see their account
- You can press a button on their profile to see a list of their followers
- You can click on any one of their followers to see their account
Steps 3 and 4 can go on forever (another example below):
MyProfile -> Followers (my followers list) -> FollowerView -> Followers (their followers list) -> FollowerView -> Followers (their followers list) -> FollowerView and so on...
However with the implementation below when run, the XCode console prints: A navigationDestination for “myApp.SomeProfile” was declared earlier on the stack. Only the destination declared closest to the root view of the stack will be used.
I have an understanding as to why this is yet am unsure how to fix this issue.  I am also if the type used as the NavigationLink value is suitable since it is Int.  Would it be better to replace it with a more custom type?
Any help would be greatly appreciated.
// Enum with custom options
enum ViewOptions: Hashable {
    case followers(Int)
    
    @ViewBuilder func view(_ path: Binding<NavigationPath>, id: Int) -> some View {
        FollowersList(path: path, id: id)
    }
}
// Root view
struct MyProfileView: View {
    @State private var path: NavigationPath = .init()
    
    var body: some View {
        NavigationStack(path: $path) {
            VStack {
                Text(myProfile.username)
                Button("See followers") {
                    path.append(ViewOptions.followers(myProfile.id))
                }
                .navigationDestination(for: ViewOptions.self) { option in
                    option.view($path, id: myProfile.id)
                }
            }
        }
    }
}
struct FollowersList: View {
    @Binding var path: NavigationPath
    var id: Int
    
    var body: some View {
        List(getFollowers(for: id), id:\.id) { follower in
            NavigationLink(follower.username, value: follower)
        }
        .navigationDestination(for: SomeProfile.self) { profile in
            switch profile.isMe {
            case true:  Text("This is your profile")
            case false: SomeProfileView(path: $path, profile: profile)
            }
        }
    }
}
struct SomeProfileView: View {
    @Binding var path: NavigationPath
    
    var profile: SomeProfile
    var body: some View {
        VStack {
            Text(profile.username)
            Button("See followers") {
                path.append(ViewOptions.followers(profile.id))
            }
        }
    }
}
// ----- Types & functions -----
// Example type for my profile
struct MyProfile: Identifiable, Hashable {
    var id: Int
    var username: String
}
// Example type for profiles reached via navigation link
// (can be my profile but with reduced functionality e.g. no follow button)
struct SomeProfile: Identifiable, Hashable {
    var id: Int
    var username: String
    let isMe: Bool
}
// example myProfile (IRL would be stored in a database)
let myProfile = MyProfile(id: 0, username: "my profile")
// example users (IRL would be stored in a database)
let meVisited = SomeProfile(id: 0, username: "my profile reached from followers list", isMe: true)
let bob       = SomeProfile(id: 1, username: "Bob", isMe: false)
let alex      = SomeProfile(id: 2, username: "Alex", isMe: false)
// example user followers (IRL would be stored in a database)
let dict: [Int : [SomeProfile]] = [
    0 : [bob, alex],
    1 : [alex, meVisited],
    2 : [alex, meVisited],
]
// example function to get followers of a user (IRL would be a network request)
func getFollowers(for id: Int) -> [SomeProfile] {
    return dict[id]!
}
 
     
    