I have an API endpoint that returns array of various items, so I have created an enum
that can hold those items and therefore I can create an array of them - more less like below
let arr: [CollectableEnum] = [
.feed(.init(id: "1")),
.clinic(.init(id: "1")),
.feed(.init(id: "2")),
]
Now I need to iterate through them and display properly in SwiftUI
I wonder, how to get an value from that enum, so I can get an ItemModel
rather than CollectableEnum
that holds that ItemModel
enum code:
enum CollectableEnum: Identifiable, Hashable {
case feed(ItemModel)
case clinic(ClinicModel)
var id: String {
switch self {
case .feed(let feed):
return feed.id
case .clinic(let clinic):
return clinic.id
}
}
// what return type should I put here?
var associatedValue {
switch self {
case .feed(let feed):
return feed
case .clinic(let clinic):
return clinic
}
}
public func hash(into hasher: inout Hasher) {
return hasher.combine(self)
}
}
Why don't you declare the associated values directly in the enum ? And use AnyObject.
Like in the following dummy example:
struct ItemModel {
var id: String
var value: Int
}
struct ClinicModel {
var id: String
var value: Double
}
enum CollectableEnum: Identifiable, Hashable {
case feed(feed: ItemModel)
case clinic(clinic: ClinicModel)
var id: String {
switch self {
case .feed(let feed):
return feed.id
case .clinic(let clinic):
return clinic.id
}
}
static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs.id == rhs.id
}
var associatedValue: AnyObject { // what return type should I put here? AnyObject
switch self {
case .feed(let feed):
return feed as AnyObject
case .clinic(let clinic):
return clinic as AnyObject
}
}
public func hash(into hasher: inout Hasher) {
return hasher.combine(self)
}
}
But, why do you need to declare associateValue ? You get it directly when you call the enum, like this
- Suppose you have declared
let myClinic = ClinicModel(id: "1", value: 10.0)
let myEnum = CollectableEnum.clinic(clinic: myClinic)
if you have a var
var collect : CollectableEnum
Then, you could write
switch collect {
case let .feed(someFeed) : // use someFeed as needed
case let .clinic(someClinic) : // use someClinic as needed
}
or equivalent, with a var
switch collect {
case .feed(var someFeed) : // use someFeed as needed
case .clinic(var someClinic) : // use someClinic as needed
}