Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
381 views
in Technique[技术] by (71.8m points)

ios - Dynamic key value type

I have a json that I decode using Codable.

struct Item: Codable {
    let data: Data // dictionary or array
}


struct Data: Codable {
    let id: Int
}

The "data" field can be an array or a dictionary.

How do I decode my json ?

example json

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You have to decode data depending on type. That means you have to first decode type and then continue depending on its value. Usually to store such items we would use an enum with associated values:

enum Item: Decodable {
    case onboarding(OnboardingData)
    case entry(EntryData)

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let type = try container.decode(String.self, forKey: .type)

        switch type {
        case "onboarding":
            let data = try container.decode(OnboardingData.self, forKey: .data)
            self = .onboarding(data)
        case "entry":
            let data = try container.decode(EntryData.self, forKey: .data)
            self = .entry(data)
        default:
            throw DecodingError.unknownType
        }
    }

    private enum CodingKeys: String, CodingKey {
        case type
        case data
    }

    private enum DecodingError: String, Error {
        case unknownType
    }
}

struct OnboardingData: Decodable {
}

struct EntryData: Decodable {
}

OnboardingData and EntryData are just type placeholders. You can change them to anything to want, e.g. an array of items. Also, you might wrap arrays inside them.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...