Swift 根据响应类型为 JSON 字段值动态选择 Codable 结构

Posted

技术标签:

【中文标题】Swift 根据响应类型为 JSON 字段值动态选择 Codable 结构【英文标题】:Swift Dynamically choose Codable struct for JSON field value based on response type 【发布时间】:2020-03-13 11:14:54 【问题描述】:

我正在使用可编码结构来处理 API JSON 响应。其中一个字段(slideData_)中的数据结构因响应所涉及的卡片类型(cardType)而异。

因此,我需要在结构中创建一个简单的条件,根据 cardType 字段中返回的值将 slideData 的值设置为 ApiCompanyProfileCardData 或 ApiPersonalProfileCardData。我一直在寻找很长一段时间,我相信 enum 和 CodingKeys 可能是要走的路,但我一直在努力实现这一点。感觉好像它应该相当简单。有人可以帮忙吗?

"card": 
    [
    "cardTitle": "Title 1", 
    "cardType": "companyprofile", 
    "cardTypeDesc": "Company profile", 
    "id": 10, 
    "imageFile": "b443709ca8d8a269ca185381bfa2ad8326af33c3.png", 
    "slideData": "cp_name": "Full Name", 
                  "cp_name_font_style": "'Nunito', sans-serif", 
                  "cp_name_font_weight": "900", 
                  "cp_name_size_quantity": "30px", 
                  "cp_name_text_color": "ff0000", 
                  "cp_title": "CEO", 
                  "cp_title_font_style": "Arial", 
                  "cp_title_font_weight": "normal", 
                  "cp_title_size_quantity": "20px", 
                  "cp_title_text_color": "000000"
                  
     ]


struct ApiCardData: Codable 

    let card: [Card]

    struct Card : Codable 
        let cardTitle: String
        let cardType: String
        let id: Int
        let imageFile: String
        let slideData: ApiCompanyProfileCardData
    

    struct ApiCompanyProfileCardData: Codable 
        let cpName: String
        let cpNameFontStyle: String
        let cpNameFontWeight: String
        let cpNameSizeQuantity: String
        let cpNameTextColor: String
        let cpTitle: String
        let cpTitleFontStyle: String
        let cpTitleFontWeight: String
        let cpTitleSizeQuantity: String
        let cpTitleTextColor: String
    

    struct ApiPersonalProfileCardData: Codable 
        let ppEmail: String
        let ppEmailFontStyle: String
        let ppEmailFontWeight: String
        let ppEmailSizeQuantity: String
        let ppEmailTextColor: String
        let ppName: String
        let ppNameFontStyle: String
        let ppNameFontWeight: String
        let ppNameSizeQuantity: String
        let ppNameTextColor: String
    


【问题讨论】:

【参考方案1】:

@N.Widds 然后你可以像下面这样构建你的结构,希望它对你有帮助。

    struct ApiCardData: Codable 

    let card: [Card]

    struct Card : Codable 
        let cardTitle: String
        let cardType: String
        let id: Int
        let imageFile: String
        let slideData: ApiCompanyProfileCardData?
        let slideApiPersonalProfileData: ApiPersonalProfileCardData?

    

struct ApiCompanyProfileCardData: Codable 
    let cpName: String
    let cpNameFontStyle: String

    enum CodingKeys: String, CodingKey 

        case cpName = "cp_name"
        case cpNameFontStyle = "cp_name_font_style"
    



struct ApiPersonalProfileCardData: Codable 
    let ppEmail: String
    let ppEmailFontStyle: String

    enum CodingKeys: String, CodingKey 

        case ppEmail = "pp_Email"
        case ppEmailFontStyle = "pp_email_font_style"
    



【讨论】:

@N.Widdes 在您的视图逻辑方面,您需要根据您的条件获取这些对象,例如 slideData != nil 或 slideApiPersonalProfileData != nil。你也必须使用guard 声明。 @JoakimDanielson 我已将这些对象更新为可选。 这样更好,但我认为您需要解释应该如何进行解码才能正确设置它们 大家好。谢谢你。是的,如果我能像 Joakim 所说的那样清楚地了解如何正确解码可选值,那将非常有帮助。

以上是关于Swift 根据响应类型为 JSON 字段值动态选择 Codable 结构的主要内容,如果未能解决你的问题,请参考以下文章

Swift JSON响应两个字段值附加到单个数组中

如何将json对象的值设置为swift 3中tableView中动态呈现的视图中的标签?

从 JSON 生成动态条件表单字段 - AngularJS1.x

Swift 解析 JSON 时出现问题:无法将“__NSCFDictionary”类型的值转换为“NSArray”错误

如何解析来自同一字段的多类型值的 json 响应?

Swift handyJson使用原理