Recommendations for how to give an enum with associated values a sort of identifier

In an application I'm working on, there's a desire to use enums with associated values but to also give each of the enum cases a sort of identifier. The code below might explain it better but I'm wondering if anyone has any recommendations for a more Swift way to accomplish this. At the moment, we're using two separate enums, but that feels because of the obvious duplication. Consider:

enum MetadataPropertyIdentifier: String, Codable {
  case filename
  case dateCreated
}

enum MetadataProperty {
  case filename(String)
  case dateCreated(Date)

  var identifier: MetadataPropertyIdentifier {
    switch self {
      case .filename: return .filename
      case .dateCreated: return .dateCreated
    }
  }
}

// The reason for the two types is that we:
//  - Want to ensure that a valid, typed value is present when setting or returning a property.
//  - Want the ability to identify a property without a value in things like menus and settings files.
//

func setProperty(_ property: MetadataProperty) {
  switch property {
    case .filename(let name):     /* Store the string somewhere. */
    case .dateCreated(let date):  /* Store the date somewhere. */
  }
}

func getProperty(_ identifier: MetadataPropertyIdentifier) {

  switch property {
    case .filename: return .filename("Untitled")
    case .dateCreated: return .date(Date())
  }
}

Given that we could have several hundred properties, this pattern can get quite tedious. The identifier is used in places like menu items, settings files where we want to refer to a specific property, but don't need a value.

MetadataProperty could be changed to make the associated value optional, but there can exist a situation where a property nil might be a valid value for a property. I'm curious if anyone has any recommendations for ways to improve such a pattern.

1 Like