如何对具有多种数据类型的JSON数组进行解码?

ruyhziif  于 2022-12-01  发布在  其他
关注(0)|答案(2)|浏览(120)

我正在尝试从一个API中解码一个JSON文件,但是value数组包含了一堆字符串和一个int结尾。当我在结构体中指定数据类型为AnyObject时,它说该结构体不符合Decodable协议。我是否遗漏了什么?有没有方法可以在没有最后一个Int的情况下提取数据?

o8x7eapl

o8x7eapl1#

您可以使用QuickType解析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)
        }
    }
}

请使用以下代码检查下面Value的值类型。

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)
    }
}
8e2ybdfx

8e2ybdfx2#

Decodable需要符合协议的具体类型。不支持Any(Object)
您可以手动将Value编码为UnkeyedContainer**。结果是strings中的字串数组和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)
    }
}

注:JSON值永远不是对象(引用类型)。

相关问题