有两个不匹配错误。 第一个是因为 yearOfBirth 变量。因为 JsonData 之一是 String (""),而其他都是 Integer。
第二个是wand变量。错误是:
期望解码字符串,但找到了字典
我的型号是:
struct harryPotter : Codable{
var name : String
var species : String
var gender : String
var house : String
var dateOfBirth : String
var yearOfBirth : Int
var ancestry : String
var eyeColour : String
var hairColour : String
var wand : String
var patronus : String
var hogwartsStudent : Bool
var hogwartsStaff : Bool
var actor : String
var alive : Bool
var image : String
}
struct wand : Codable{
var wood : String
var core : String
var length : Int
}
JSON 数据链接: JSON
该错误清楚地表明
wand
类型应该是 Wand
而不是 String
。
此外,对于多种类型的变量,可以使用枚举。
此外,对于像
gender
这样的选项,您应该使用 enum
来代替。
所以:
import Foundation
// MARK: - Input
struct Input: Codable {
let name: String
let species: Species
let gender: Gender
let house, dateOfBirth: String
let yearOfBirth: YearOfBirth
let ancestry, eyeColour, hairColour: String
let wand: Wand
let patronus: String
let hogwartsStudent, hogwartsStaff: Bool
let actor: String
let alive: Bool
let image: String
}
enum Gender: String, Codable {
case female = "female"
case male = "male"
}
enum Species: String, Codable {
case cat = "cat"
case halfGiant = "half-giant"
case human = "human"
case werewolf = "werewolf"
}
// MARK: - Wand
struct Wand: Codable {
let wood, core: String
let length: Length
}
enum Length: Codable {
case double(Double)
case string(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(Double.self) {
self = .double(x)
return
}
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
throw DecodingError.typeMismatch(Length.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for Length"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .double(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
}
}
}
enum YearOfBirth: 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(YearOfBirth.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for YearOfBirth"))
}
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)
}
}
}
typealias Inputs = [Input]