【问题标题】:Nested Json Decoder Swift嵌套 Json 解码器 Swift
【发布时间】:2018-06-30 17:16:13
【问题描述】:

解码 json 时,我得到 nil 响应。我有嵌套的json。不管我不知道,我解析的方式是否正确。 这是我的代码。

struct ProfileModelClass : Codable {
    let status : Int?
    let message : String?
    let profile : Profile?

    enum CodingKeys: String, CodingKey {

        case status = "status"
        case message = "message"
        case profile
    }
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        status = try values.decodeIfPresent(Int.self, forKey: .status)
        message = try values.decodeIfPresent(String.self, forKey: .message)
        profile = try Profile(from: decoder)
    }
}


struct Profile : Codable {
    let name : String?
    let email : String?
    let verified : Bool?
    let phone : Int?
    let articletype : [String]?
    let ai_score : Int?
    let bfi : String?
    let pic : String?
    let cover : String?
    let background : String?
    let layout : String?
    let customcolors : Customcolors?
    let widgets : [String]?
    let basket : [Basket]?
    let joindate : String?
    let linklink_id : String?
    let gps : Bool?
    let radius : Int?
    let showme : Bool?

    enum CodingKeys: String, CodingKey {

        case name = "name"
        case email = "email"
        case verified = "verified"
        case phone = "phone"
        case articletype = "articletype"
        case ai_score = "ai_score"
        case bfi = "bfi"
        case pic = "pic"
        case cover = "cover"
        case background = "background"
        case layout = "layout"
        case customcolors
        case widgets = "widgets"
        case basket = "basket"
        case joindate = "joindate"
        case linklink_id = "linklink_id"
        case gps = "gps"
        case radius = "radius"
        case showme = "showme"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        name = try values.decodeIfPresent(String.self, forKey: .name)
        email = try values.decodeIfPresent(String.self, forKey: .email)
        verified = try values.decodeIfPresent(Bool.self, forKey: .verified)
        phone = try values.decodeIfPresent(Int.self, forKey: .phone)
        articletype = try values.decodeIfPresent([String].self, forKey: .articletype)
        ai_score = try values.decodeIfPresent(Int.self, forKey: .ai_score)
        bfi = try values.decodeIfPresent(String.self, forKey: .bfi)
        pic = try values.decodeIfPresent(String.self, forKey: .pic)
        cover = try values.decodeIfPresent(String.self, forKey: .cover)
        background = try values.decodeIfPresent(String.self, forKey: .background)
        layout = try values.decodeIfPresent(String.self, forKey: .layout)
        customcolors = try Customcolors(from: decoder)
        widgets = try values.decodeIfPresent([String].self, forKey: .widgets)
        basket = try values.decodeIfPresent([Basket].self, forKey: .basket)
        joindate = try values.decodeIfPresent(String.self, forKey: .joindate)
        linklink_id = try values.decodeIfPresent(String.self, forKey: .linklink_id)
        gps = try values.decodeIfPresent(Bool.self, forKey: .gps)
        radius = try values.decodeIfPresent(Int.self, forKey: .radius)
        showme = try values.decodeIfPresent(Bool.self, forKey: .showme)
    }

}

struct Basket : Codable {
    let mood : String?
    let score : Int?

    enum CodingKeys: String, CodingKey {

        case mood = "mood"
        case score = "score"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        mood = try values.decodeIfPresent(String.self, forKey: .mood)
        score = try values.decodeIfPresent(Int.self, forKey: .score)
    }

}

struct Customcolors : Codable {
    let text : String?
    let opacity : Double?
    let bg : String?

    enum CodingKeys: String, CodingKey {

        case text = "text"
        case opacity = "opacity"
        case bg = "bg"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        text = try values.decodeIfPresent(String.self, forKey: .text)
        opacity = try values.decodeIfPresent(Double.self, forKey: .opacity)
        bg = try values.decodeIfPresent(String.self, forKey: .bg)
    }

}

这也是我的 json 响应

{"status":1,"message":"Fetched data","profile":{"name":"Prem Kumar","email":"a@a.com","verified":true ,"电话":"+91998532542","articletype":["fun","article","insight"],"ai_score":100,"bfi":"100%","pic":"", "cover":"","background":"","layout":"3column","customcolors":{"text":"#e7e7e7","opacity":"0.8","bg":"# 272323"},"widgets":["interest","education","hobbies","media","habits","professional","weather","smabusinesstypes","orderhistory","newspaper","国家”,“愿望清单”],“篮子”:[{“心情”:“悲伤”,“得分”:5},{“心情”:“恐惧”,“得分”:4},{“心情”: “愤怒”,“得分”:4},{“心情”:“厌恶”,“得分”:3},{“心情”:“讨厌”,“得分”:3},{“心情”:“嫉妒","score":2},{"mood":"satisfaction","score":0},{"mood":"competetive","score":0},{"mood":"frustration", "score":0},{"mood":"joy","score":0},{"mood":"elevation","score":0},{"mood":"love","score ":0},{"mood":"精力充沛","score":0}],"joindate":"2017-12-10T07:50:06.379Z","linklink_id":"5a435b0a5c23904f78b76542","gps" :true,"radius":5,"showme":true}}

【问题讨论】:

  • 为什么要指定初始化器?编译器免费为您提供这些。
  • 哦,我会改变的,有时我会变为零

标签: ios json swift json-deserialization


【解决方案1】:

请阅读错误信息。他们很清楚

  • Profile 中,键phone 的值为String
  • CustomColors 中,键opacity 的值为String

双引号中的每个值都是String,甚至是"0""1.0""false"

您可以删除所有编码键和所有初始化程序,因为它们是隐式提供的。并且不要随便声明一切都是可选的。仅将那些可能缺少相应键的属性声明为可选。此特定 JSON 无需任何可选属性即可工作

【讨论】:

  • 我们不需要将所有键都设置为可选?
  • 是的,我们没有。试试看。
  • 如何处理空值,我得到“预期的字符串值,但发现是空值。”。
  • 在这种情况下,将属性设为可选。
【解决方案2】:

正如@vadian 所说,删除所有初始化程序并且不要立即将所有内容声明为可选。识别响应中可能缺少的键,并仅将这些键声明为可选项。您提供的 JSON 不需要任何选项。

为了更清楚,请检查以下代码

struct ProfileModelClass : Codable {
    let status : Int
    let message : String
    let profile : Profile
}

struct Profile : Codable {
    let name : String
    let email : String
    let verified : Bool
    let phone : String
    let articletype : [String]
    let ai_score : Int
    let bfi : String
    let pic : String
    let cover : String
    let background : String
    let layout : String
    let customcolors : Customcolors
    let widgets : [String]
    let basket : [Basket]
    let joindate : String
    let linklink_id : String
    let gps : Bool
    let radius : Int
    let showme : Bool
}

struct Customcolors : Codable {
    let text : String
    let opacity : String
    let bg : String
}

struct Basket : Codable {
    let mood : String
    let score : Int
}

【讨论】:

  • 您甚至可以删除所有编码键。仅当属性应该具有不同的名称作为键时才需要它们。
  • 感谢您的信息 :) 更新了我的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-25
  • 2021-10-24
相关资源
最近更新 更多