【问题标题】:Swift Dynamically choose Codable struct for JSON field value based on response typeSwift 根据响应类型为 JSON 字段值动态选择 Codable 结构
【发布时间】: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
    }

}

【问题讨论】:

    标签: swift codable


    【解决方案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 所说的那样清楚地了解如何正确解码可选值,那将非常有帮助。
    猜你喜欢
    • 2019-12-20
    • 2012-08-30
    • 2020-10-14
    • 2020-06-14
    • 1970-01-01
    • 2019-05-12
    • 1970-01-01
    • 2021-01-30
    • 2019-04-12
    相关资源
    最近更新 更多