I'm trying to decode a JSON file from an
CodePudding user response:
You can use QuickType to parse the model data from JSON.
// MARK: - DataModel
struct DataModel: Codable {
let title: String
let blanks: [String]
let value: [Value]
}
enum Value: Codable {
case integer(Int)
case string(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(Int.self) {
self = .integer(x)
return
}
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
throw DecodingError.typeMismatch(Value.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for Value"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .integer(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
}
}
}
Please use the following code to check the value type of Value
below.
let jsonData = jsonString.data(using: .utf8)!
let dataModel = try? JSONDecoder().decode(DataModel.self, from: jsonData)
dataModel?.value.forEach { value in
switch value {
case .integer(let intValue):
print(intValue)
case .string(let stringValue):
print(stringValue)
}
}
CodePudding user response:
Decodable
expects concrete types which conform to the protocol. Any(Object)
is not supported.
You could decode Value
as UnkeyedContainer
manually. The result is the string array in strings
and the integer value in integer
.
struct DataModel: Decodable {
let title: String
let blanks: [String]
let value: Value
}
struct Value: Decodable {
let strings : [String]
let integer : Int
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
var stringData = [String]()
guard let numberOfItems = container.count else {
throw DecodingError.dataCorruptedError(in: container,
debugDescription: "Number of items in the array is unknown")
}
while container.currentIndex < numberOfItems - 1 {
stringData.append(try container.decode(String.self))
}
strings = stringData
integer = try container.decode(Int.self)
}
}
Side note: A JSON value is never an object (reference type).