Swift:如何通过自定义枚举自动为StationDetailsDTO的stateName赋值?
Hey there! Ditching those messy if-else chains for enums is a great call—it makes your code way more scalable and readable. Let's walk through how to implement this properly, tailored to your StationDetailsDTO setup.
First, let's adjust your enum to directly tie each state ID to its corresponding name. Instead of using String raw values, we'll use Int raw values that match your stateID integers, and add a computed property for the human-readable display name:
enum State: Int { case a = 0 case b = 1 case c = 2 var displayName: String { switch self { case .a: return "A" case .b: return "B" case .c: return "C" } } }
This way, each enum case maps directly to the stateID from your API, and the displayName gives you the exact string you need for stateName.
Next, let's integrate this into your StationDetailsDTO. Since you're using ObjectMapper, we have two clean options to handle the mapping:
Option 1: Set stateName During API Parsing
If you want to handle the mapping right when the API response is parsed, update your mapping(map:) function:
class StationDetailsDTO: Object, Mappable { @objc dynamic var stateID = 0 @objc dynamic var stateName = "" required convenience init?(map: Map) { self.init() } func mapping(map: Map) { stateID <- map["stateID"] // Map stateID to stateName using the enum if let state = State(rawValue: stateID) { stateName = state.displayName } else { // Handle unknown stateIDs (optional: set a default or log an error) stateName = "Unknown" } } }
Option 2: Auto-Update stateName with a Computed Property
If you want stateName to automatically update whenever stateID changes (even if you modify it later), replace the stored stateName property with a computed one:
class StationDetailsDTO: Object, Mappable { @objc dynamic var stateID = 0 // Computed property instead of stored var stateName: String { if let state = State(rawValue: stateID) { return state.displayName } return "Unknown" } required convenience init?(map: Map) { self.init() } func mapping(map: Map) { stateID <- map["stateID"] } }
Why This Beats If-Else Chains
- Scalability: Adding a new state only requires adding a new case to the enum—no more endless else-if blocks.
- Readability: All ID-to-name mappings live in one place, making it easy to reference or update.
- Type Safety: You can’t accidentally assign an invalid state name, since all valid options are defined in the enum.
If you were curious about using associated values (though it’s less necessary here), here’s how that would look (it’s a bit more verbose but works):
enum State { case a(id: Int) case b(id: Int) case c(id: Int) init?(id: Int) { switch id { case 0: self = .a(id: 0) case 1: self = .b(id: 1) case 2: self = .c(id: 2) default: return nil } } var displayName: String { switch self { case .a: return "A" case .b: return "B" case .c: return "C" } } }
But the raw Int value enum approach is cleaner for your specific use case, since the ID directly corresponds to the enum case.
Hope this helps you clean up that code! 😊
内容的提问来源于stack exchange,提问作者Alvin

