Generic type protocol Published property

256 views Asked by At

I got x data models (struct) that conform to a protocol. I want to have in my viewModel a @Pubished property that represents one of those type and access each property to assign in the UI, Why is this approach not possible? I got the compiler is unable to type check.

protocol HumanProtocol {       
  associatedtype Human      
}

struct Female: HumanProtocol {
  typealias Human = Female
  var name:String
}

struct Male: HumanProtocol {
  typealias Human = Male
  var name:String
}

class HumanViewModel:ObservableObject {      
  @Published var selectedHuman: Any HumanProtocol? 
    init(selectedHuman:Any HumanProtocol) {
    self.selectedHuman = selectedHuman
  }
}

wanted Result:

@StateObject var humanVM = HumanViewModel(selectedHuman:Male(name:""))

TextField("Nickname", text: $humanVM.selectedHuman.name )
          .modifier(TextFieldModifier(width: 250, height: 30))
          .padding(.top))
1

There are 1 answers

0
jnpdx On

In this case, it would be better to use a generic than trying to use any:

class HumanViewModel<T: HumanProtocol>: ObservableObject {
    
    @Published var selectedHuman: T
    
    init(selectedHuman: T) {
        self.selectedHuman = selectedHuman
    }
    
}

struct Example: View {
    @StateObject private var vm = HumanViewModel(selectedHuman: Male(name: "Test"))
    
    var body: some View {
        TextField("", text: $vm.selectedHuman.name)
    }
}

Here, the type of HumanViewModel can be inferred because Male is passed to it.