Search code examples
xcodeforeachswiftuiviewmodel

Issues with ForEach Loop over view model array causing Xcode compile error - SwiftUI


I am getting an unknown compile error when I try to add a ForEach loop with a subviewmodel of my main view model:

enter image description here

I've seen this error in a similar situation before, I am wondering if there are any possible common errors with ViewModels in ForEach loops that could be leading to this error?

Here is my SwiftUI View with the ForEach loop:

struct GroupHubView: View {
    @ObservedObject var groupHubVM: GroupHubViewModel
    
    var body: some View {
        NavigationView {
            ScrollView {
                VStack {
                    ForEach(groupHubVM.activeGroupViewModels) { groupCellVM in
                        GroupCellView(groupCellVM: groupCellVM)
                    }
                }
            }
        }

And here is the ViewModel, that has a combine-populated list of sub-viewmodels that starts out as an empty array, before I call loadActiveGroups():

class GroupHubViewModel: ObservableObject {
    
    @Published var groupRepository: GroupStoreType
    @Published var currentUser: CurrentUserType
    
    @Published var activeGroupViewModels: [GroupCellViewModel] = [GroupCellViewModel]()
    @Published var pendingInviteViewModels: [GroupCellViewModel] = [GroupCellViewModel]()
    
    private var cancellables = Set<AnyCancellable>()
    
    
    init(groupRepository: GroupStoreType, currentUser: CurrentUserType = CurrentUserProfile.shared) {
        self.groupRepository = groupRepository
        self.currentUser = currentUser
        
        self.loadActiveGroups()
        self.loadPendingGroups()
    }
    
    func loadActiveGroups() {
        self.groupRepository.accountabilityGroupsPublisher.map { groups in
            groups.filter { group in
                if group.members?.contains(where: { $0.userId == self.currentUser.currentUser!.id && $0.membershipStatus == .active }) == true {
                    return true
                } else {
                    return false
                }
            }
            .map { group in
                GroupCellViewModel(groupRepository: self.groupRepository, accountabilityGroup: group)
            }
        }
        .assign(to: \.activeGroupViewModels, on: self)
        .store(in: &cancellables)
    }

Errors: As soon as I add this: ForEach(groupHubVM.activeGroupViewModels) { groupCellVM in I get the full unknown compile error on the view.

If I just add the ForEach, like this: ForEach(groupHubVM.activeGroupViewModels), I get this error saying that "generic parameter "Content" could not be inferred: enter image description here

Edited: My GroupCellViewModel is very simple at this point - it just holds the GroupRepository and the specific group at this point:

class GroupCellViewModel: ObservableObject {
    
    @Published var groupRepository: GroupStoreType
    
    @Published var group: AccountabilityGroup
    
    private var cancellables = Set<AnyCancellable>()
    
    init(groupRepository: GroupStoreType, currentUser: CurrentUserType = CurrentUserProfile.shared, accountabilityGroup: AccountabilityGroup) {
        self.groupRepository = groupRepository
        self.group = accountabilityGroup
    }
    
}

Solution

  • Based on the comments above by loreipsum and George, my issue was that GroupCellViewModel didn't conform to Identifiable. I fixed this and that solved the issue:

    class GroupCellViewModel: ObservableObject, Identifiable {
        
        @Published var groupRepository: GroupStoreType
        
        @Published var group: AccountabilityGroup
        
        private var cancellables = Set<AnyCancellable>()
        
        init(groupRepository: GroupStoreType, currentUser: CurrentUserType = CurrentUserProfile.shared, accountabilityGroup: AccountabilityGroup) {
            self.groupRepository = groupRepository
            self.group = accountabilityGroup
        }
        
    }