Reading in from small JSON file (cut/pasted small sample) and bring it into structs. I am using CodingKeys to change the "string key" to match what I want in the struct. I am changing the "whoresponds" key to "respondingPilot". That is all working fine. However, I also want to look at the values on that property and change on-the-fly the value brought in. For example, if I get the string "BOTH", I want to change my data that is stored to "CAPT & F/O". Same if I see "FO", I want that changed to "F/O" as it read in. Sample below reads in fine but will not make the changes. Still learning but must be something simple I am missing. Thanks!
struct CheckListsJSON: Codable {
var name: String
var checklistItems: [ChecklistItemsJSON]
}
struct ChecklistItemsJSON: Codable, Identifiable {
var challenge: String
var respondingPilot: PilotResponding
let id = UUID()
private enum CodingKeys: String, CodingKey {
case challenge
case respondingPilot = "whoresponds"
}
enum PilotResponding: String, Codable {
case CPT = "CAPT"
case FO = "F/O"
case PF = "PF"
case PM = "PM"
case BOTH = "CAPT & F/O"
}
}
let jsonAC = "{\"name\": \"After Start\", \"checklistItems\": [{\"challenge\": \"Generators\", \"whoresponds\": \"CPT\"}, {\"challenge\": \"Isolation Valve\", \"whoresponds\": \"FO\"}}"
let fileData = Data(jsonAC.utf8)
do {
let decodedData = try JSONDecoder().decode(CheckListsJSON.self, from: fileData)
print("decoded:", decodedData)
} catch {
print(error)
}
CodePudding user response:
Decoding a string to an enum works like CodingKeys. The raw value is the string you receive and the case is the case.
Unfortunately the character set of enum cases is restricted. Space characters, / and & are not allowed.
You could write something like this, raw values which match the case can be omitted.
enum PilotResponding: String, Codable {
case CAPT = "CPT"
case F_O = "FO"
case PF, PM
case CAPT_F_O = "BOTH"
}
CodePudding user response:
You can add a custom init for decoding to your enum and translate the codes in it to the correct enum case
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let code = try container.decode(String.self)
switch code {
case "CPT":
self = .CPT
case "FO":
self = .FO
case "BOTH":
self = .BOTH
case "PF":
self = .PF
case "PM":
self = .PM
default:
fatalError() // change this to throw an error
}
}
