N.Widds
N.Widds

Reputation: 277

Swift Dynamically choose Codable struct for JSON field value based on response type

I'm using a codable struct to handle an API JSON response. The data structure in one of the fields (slideData_ varies depending on the type of card the response relates to (cardType).

I therefore need to make a simple conditional in the struct that sets the value of slideData to be either ApiCompanyProfileCardData or ApiPersonalProfileCardData based on the value returned in the cardType field. I've been searching for quite a while and I believe enum and CodingKeys are probably the way to go but I'm stuck trying to implement this. It feels as though it should be fairly straightforward. Can somebody please help?

{"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
    }

}

Upvotes: 0

Views: 111

Answers (1)

Ram
Ram

Reputation: 804

@N.Widds Then you can form your struct like below, Hope it helps you.

    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"
    }

}
}

Upvotes: 0

Related Questions