Home > Back-end >  How to make a binding value conform to Equatable in SwiftUI
How to make a binding value conform to Equatable in SwiftUI

Time:04-09

I am getting the following error when I try to compare values in the task modifier.

Operator function '==' requires that 'Binding' conform to 'Equatable'

How can I make Binding confirm to Equatable? The non-binding ordinary NotificationDetail already confirms to Equatable.

@ObservedObject var notificationsViewModel = NotificationsViewModel.shared
//NotificationsViewModel does a API call and puts the fetched data in the Notifications Model


var body: some View {

VStack {
      ForEach($notificationsViewModel.notifications.notificationsDetails) { $notificationsDetail in
                 VStack(alignment: .leading) {
                    if notificationsDetail.notificationsCategoriesId == 2 {
                   
                        NotificationsFriendRequestCell(notificationsDetail: $notificationsDetail, viewModel: viewModel, notificationsViewModel: notificationsViewModel, tabSelection: $tabSelection) //ReceiveFriendRequestCell(user: user, viewModel: viewModel)
                    }
                    
                else if notificationsDetail.notificationsCategoriesId == 3 {
                    
                    NotificationsFriendRequestApprovedCell(notificationsDetail: $notificationsDetail, viewModel: viewModel, notificationsViewModel: notificationsViewModel, tabSelection: $tabSelection)
                    }
    
                }

                .task { //task modifier for infinite scrolling

               //BELOW LINE GETTING ERRROS
                    if $notificationsDetail == $notificationsViewModel.notifications.notificationsDetails.last { 
                            print("task modifier last item")
                            numberOfSkips  = 10
                        notificationsViewModel.getMyNotifications(isOnlyUnread: false, skip: numberOfSkips, limit: 10)
                       }
            }

           } //ForEach end
} //VStack end

Model

struct Notifications: Codable, Identifiable {
    
    let id = UUID()
    let numberOfNotifications: Int
    var notificationsDetails: [NotificationsDetail]

        enum CodingKeys: String, CodingKey {
            case numberOfNotifications = "number_of_notifications"
            case notificationsDetails = "notifications"
        }
}

struct NotificationsDetail: Codable, Identifiable, Equatable {
    let id: Int
    let notificationsCategoriesId: Int
    let questionsUsersName: String?
  
    enum CodingKeys: String, CodingKey {
        case id = "notifications_id"
        case notificationsCategoriesId = "notifications_categories_id"
        case questionsUsersName = "questions_users_name"
        
    }

 static var example = NotificationsDetail(id: 0, notificationsCategoriesId: 1, questionsId: 1, questionsUsersName: "")

    init(id: Int, notificationsCategoriesId: Int, questionsUsersName: String?) {
        self.id = id
        self.notificationsCategoriesId = notificationsCategoriesId
        self.questionsUsersName = questionsUsersName
        
    }


}

ViewModel

class NotificationsViewModel: ObservableObject {
static let shared = NotificationsViewModel()
@Published var notifications: Notifications = Notifications.example

init(){
  A() 
}

func A () {
 //do API calls and put data in @Published var notifications
}

I tried tweaking the values by removing or adding $ mark but get other errors...

if notificationsDetail == notificationsViewModel.notifications.notificationsDetails.last 

//Error: Reference to captured var 'notificationsDetail' in concurrently-executing code
if $notificationsDetail == notificationsViewModel.notifications.notificationsDetails.last 

//Error: Binary operator '==' cannot be applied to operands of type 'Binding<[NotificationsDetail]>.Element' (aka 'Binding<NotificationsDetail>') and '((NotificationsDetail) throws -> Bool) throws -> NotificationsDetail?'

Any advice would be highly appreciated! Thanks in advance.

CodePudding user response:

The reason for the error is you are handing your closure a binding through your ForEach, but you want to compare to the value of this binding. Accessing it via $ and .wrappedValue should work here. So change your code to:

if $notificationsDetail.wrappedValue == notificationsViewModel.notifications.notificationsDetails.last
  • Related