How to get enum associated type?

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)
  }
  
}

Accepted Reply

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
    }

Replies

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
    }