Optional Protocol Type

Hi


I have a protocol as follows:

protocol Profile: Codable, Identifiable {
    var id: String { get }
    var name: String { get }
}


With 2 implemenations as follows:

struct Customer: Profile {
    let id: String
    let name: String
    let country: String
}

struct Contractor: Profile {
    let id: String
    let name: String
    let trade: String
    let companyName: String
}


I have a struct that encapsulates either the customer or contractor, but I don't what type of profile it will be at initialization time. So something like:

final class UserData: ObservableObject, Codable {
    var account: Profile?
}


But the code doesn't compile with the error:

Protocol 'Profile' can only be used as a generic constraint because it has Self or associated type requirements.


How I'd like to use UserData is by:

var user = UserData()
user.account = getAccount()

func getAccount() -> Profile? {
   // decode JSON from file, returning a Custoemr or Contractor
   return Customer(id: "123", name: "Bill", country: "USA")
}

I'm struggling to assign account to an optional protocol. Appreciate any help and guidence.


Thanks

Why do you define Profile as a Protocol and not a class ?


Something like:


protocol Profile: Codable, Identifiable {
    var id: String { get }
    var name: String { get }
}
class AProfile: Profile {
    var id: String
    var name: String
}

//With 2 implemenations as follows:
struct Customer: Profile {
    let id: String
    let name: String
    let country: String
}
 
struct Contractor: Profile {
    let id: String
    let name: String
    let trade: String
    let companyName: String
}



I have questions however:

- why redefine constant let id and let name for Customer and Contarctor ?

- typo in accoount vs account

Thanks for the reply. Fixed the typo. The implementation of id and name are immutable once the instance has been created. If I undersrtand your answer UserData would be:

final class UserData: ObservableObject, Codable {
   var account: AProfile?
}


Is that what you mean?

Yes, that's what I thought.

You probably also have to make Customer and Contractor classes, not structs. This whole architecture looks like it needs reference types, not value types. If you want to assign an instance of Customer to UserData.account, it has to be a sub-class of AProfile.

Optional Protocol Type
 
 
Q