首页 > 解决方案 > 如何在 Swift 中解码 JSON 字典类型的属性?

问题描述

我目前在测试中遇到以下错误:

在此处输入图像描述

如果我正确理解了这个问题,那么我需要将我的字典转换为解码器。

目前我有下一个代码:

static var validConfirmAuthorizationData: [String: Any] { return json("valid_confirm_authorization_data") }

它具有以下结构:

{
    "data": {
        "id": "1",
        "success": true
    }
}

以及我与可解码器一起使用的响应类本身:

public struct SEConfirmAuthorizationResponse: Decodable {
    public let id: String
    public let success: Bool

    enum CodingKeys: String, CodingKey {
        case data
    }

    enum DataCodingKeys: String, CodingKey {
        case id
        case success
    }

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let dataContainer = try container.nestedContainer(keyedBy: DataCodingKeys.self, forKey: .data)
        id = try dataContainer.decode(String.self, forKey: .id)
        success = try dataContainer.decode(Bool.self, forKey: .success)
    }
}

标签: iosjsonswiftcodable

解决方案


原来解决问题如下。

首先,我创建了SpecDecodableModel

public struct SpecDecodableModel<T: Decodable> {
    static func create(from fixture: [String: Any]) -> T {
        let decoder = JSONDecoder()
        decoder.dateDecodingStrategyFormatters = [DateUtils.dateFormatter, DateUtils.ymdDateFormatter]
        let fixtureData = Data(fixture.jsonString!.utf8)
        return try! decoder.decode(T.self, from: fixtureData)
    }
}

之后,我可以将我的JSON结构转换为所需的类型。

现在回到原来的问题,我可以修复它如下:

let fixture = DataFixtures.validConfirmAuthorizationData
let response = SpecDecodableModel<SEConfirmAuthorizationResponse>.create(from: fixture)

更新

public extension Dictionary {

    var jsonString: String? {
        if let data = try? JSONSerialization.data(withJSONObject: self, options: []),
            let string = String(data: data, encoding: String.Encoding.utf8) {
            return string
        }
        return nil
    }
}

推荐阅读