Swift JSON 类型不匹配[重复]

问题描述 投票:0回答:1

有两个不匹配错误。 第一个是因为 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

ios json swift
1个回答
0
投票

该错误清楚地表明

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]
© www.soinside.com 2019 - 2024. All rights reserved.