【问题标题】:I return a NIL using JSON Codable in Swift 4 - trying to return a value from a nested JSON example我在 Swift 4 中使用 JSON Codable 返回一个 NIL - 尝试从嵌套的 JSON 示例返回一个值
【发布时间】:2019-08-15 08:32:56
【问题描述】:

我正在尝试从嵌套结构中检索 JSON 数据。我在“jsonString”中展示了一个精简的版本——我通过打印语句复制了返回结果。我错过了什么?我想要的只是这个 JSON 数据中的 ItemCount 数字。任何帮助,将不胜感激。谢谢!

let jsonString = """

{
    "?xml": "Json Codeable- Swift",
    "FHRSEstablishment": {
        "Header": {
            "#text":"",
            "ExtractDate":"2019-08-10",
            "ItemCount":"3789",
            "ReturnCode":"Success",
            "PageNumber":"1",
            "PageSize":"100",
            "PageCount":"38"
        }
    }
}
"""
let jsonDdata = Data(jsonString.utf8)



//rootStruct - 1
struct ratingFive : Codable {
    let xml : String?
    let fHRSEstablishment : FHRSEstablishment?


    enum CodingKeys: String, CodingKey {
        case xml = "?xml"
        case fHRSEstablishment = "FHRSEstablishment"
    }
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        xml = try values.decodeIfPresent(String.self, forKey: .xml)
        fHRSEstablishment = try FHRSEstablishment(from: decoder)
    }

}

//Struct1 - 1.1
struct FHRSEstablishment : Codable {
    let header : Header?

    enum CodingKeys: String, CodingKey {
        case header
    }
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        header = try Header(from: decoder)
    }
}

//Struct2 - 1.1.1
struct Header : Codable {

    let text : String?
    let extractDate : String?
    let itemCount : String?
    let pageCount : String?
    let pageNumber : String?
    let pageSize : String?
    let returnCode : String?


    enum CodingKeys: String, CodingKey {
        case text = "#text"
        case extractDate = "ExtractDate"
        case itemCount = "ItemCount"
        case pageCount = "PageCount"
        case pageNumber = "PageNumber"
        case pageSize = "PageSize"
        case returnCode = "ReturnCode"
    }
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        text = try values.decodeIfPresent(String.self, forKey: .text)
        extractDate = try values.decodeIfPresent(String.self, forKey: .extractDate)
        itemCount = try values.decodeIfPresent(String.self, forKey: .itemCount)
        pageCount = try values.decodeIfPresent(String.self, forKey: .pageCount)
        pageNumber = try values.decodeIfPresent(String.self, forKey: .pageNumber)
        pageSize = try values.decodeIfPresent(String.self, forKey: .pageSize)
        returnCode = try values.decodeIfPresent(String.self, forKey: .returnCode)
    }

}

do {
    let ratingResult = try JSONDecoder().decode(ratingFive.self, from: jsonDdata)
    print(ratingResult)// RETURNS:
    //ratingFive(xml: Optional("Json Codeable- Swift"), fHRSEstablishment: Optional(__lldb_expr_1.FHRSEstablishment(header: Optional(__lldb_expr_1.Header(text: nil, extractDate: nil, itemCount: nil, pageCount: nil, pageNumber: nil, pageSize: nil, returnCode: nil)))))

    print(ratingResult.xml) //RETURNS:
    //Optional("Json Codeable- Swift")

    print(ratingResult.fHRSEstablishment) //RETURNS:
    //Optional(__lldb_expr_1.FHRSEstablishment(header: Optional(__lldb_expr_1.Header(text: nil, extractDate: nil, itemCount: nil, pageCount: nil, pageNumber: nil, pageSize: nil, returnCode: nil))))

    print(ratingResult.fHRSEstablishment?.header?.itemCount) //RETURNS:
    //NIL

}catch {
    print(error)
}

当我想要的只是 ItemCount 时,我一直返回 NIL。

【问题讨论】:

    标签: json swift data-structures jsondecoder swift-structs


    【解决方案1】:

    非常感谢您的回复!我选择了精简版并删除了 init:

    //rootStruct - 1
    struct ratingFive: Codable {
        let xml : String?
        let fHRSEstablishment: FHRSEstablishment?
    
        enum CodingKeys: String, CodingKey {
            case xml = "?xml"
            case fHRSEstablishment = "FHRSEstablishment"
        }
    }
    
    //Struct1 - 1.1
    struct FHRSEstablishment : Codable {
        let Header : Header
    }
    
    //Struct2 - 1.1.1
    struct Header : Codable {
        let ItemCount : String?
    }
    
    
    do {
        let ratingResult = try JSONDecoder().decode(ratingFive.self, from: jsonDdata)
        print(ratingResult.fHRSEstablishment!.Header.ItemCount) //RETURNS: 3789!!!
    }catch {
        print(error)
    }
    

    【讨论】:

    • 注意:Swift 中,class/enum/struct 类型应以 大写 字母开头。即RatingFive 而不是ratingFive。并且成员名称应以 小写 字母开头,例如 let header 而不是 let Header
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    相关资源
    最近更新 更多