Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

@Published property wrapper doesn't allow tuple sets

import SwiftUI

class aViewModel: ObservableObject {
    @Published var abc: Set<(aa:String,bb:String,cc:Double,dd:Int)> = []  // Type '(aa: String, bb: String, cc: Double, dd: Int)' does not conform to protocol 'Hashable'
    
    func fetchData() async throws {
        // Url Stuff
    }
}

struct ContentView: View {
    @StateObject var ViewModel = aViewModel()
    
    var body: some View {
        ...
            .task {
                do {
                    try await ViewModel.fetchData()
                } catch {
                // Show Alert
            }
        }
        ForEach($ViewModel.abc,id: \.self) { e in
            //Using for stuff..
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

I tried not putting <(aa:String,bb:String,cc:Double,dd:Int)> but this causes to be any set. Because any is not Hashable it causes error. I can’t even change to array because set fixes an bug. If i try to solve the bug with array it causes big performance drops. What do I need to do in this situation?

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The issue you’re facing arises because the elements of the set in your aViewModel class do not conform to the Hashable protocol. Sets in Swift require their elements to be hashable in order to ensure uniqueness.

To resolve this, you need to make your tuple conform to the Hashable protocol. Here’s an updated version of your code:

class aViewModel: ObservableObject {
    @Published var abc: Set<ABC> = []

    func fetchData() async throws {
        // Url Stuff
    }
}

struct ABC: Hashable {
    let aa: String
    let bb: String
    let cc: Double
    let dd: Int
}

struct ContentView: View {
    @StateObject var viewModel = aViewModel()

    var body: some View {
        // ...
        .task {
            do {
                try await viewModel.fetchData()
            } catch {
                // Show Alert
            }
        }
        ForEach(Array(viewModel.abc), id: \.self) { e in
            // Using for stuff..
        }
    }
}

In this updated code, a separate struct named ABC is defined, which represents the tuple elements. This struct now conforms to the Hashable protocol. The abc property in the aViewModel class is updated to use the ABC struct, and the ForEach loop is modified to convert the set to an array using Array(viewModel.abc). This allows it to iterate over the elements properly.

With these changes, you should no longer encounter the error related to the Hashable protocol, and your code should work as expected.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading