0

what im working with

"meta_data": [
        {
            "id": 4116,
            "key": "_wcf_frm_created",
            "value": ""
        },
        {
            "id": 4117,
            "key": "_wcf_custom_degin_checkbox",
            "value": ""
        },
        {
            "id": 4118,
            "key": "_wcf_frm_data",
            "value": {
                "1": {
                    "1": "",
                    "2": "",
                    "3": "chk_box"
                }
            }
        },
        {
            "id": 4142,
            "key": "_vendor_select",
            "value": "6484"
        },
        {
            "id": 4143,
            "key": "_vendor_percentage",
            "value": "100"
        },
        {
            "id": 4144,
            "key": "_vendor_pro_cat",
            "value": "Sushi"
        },
        {
            "id": 4156,
            "key": "slide_template",
            "value": "default"
        }
    ],
    "_links": {
        "self": [
            {
                "href": "https://xxxxxx.net/wp-json/wc/v3/products/6489"
            }
        ],
        "collection": [
            {
                "href": "https://xxxxxx.net/wp-json/wc/v3/products"
            }
        ]
    }

what I currently have

struct woocomerceProduct : Decodable, Encodable
{
    var meta_data : [Meta_data?]
    var _links : [_Links?]


}

    struct Meta_data : Decodable, Encodable
{
    var id : Int?
    var key : String?
    var value : String?
}
   struct One : Decodable, Encodable
{
        var one : String?
        var two : String?
        var three : String?
}

struct _Links : Decodable, Encodable
{
    var SELF : [String?]
    var collectio : [String?]
}

ok so here are the questions. 1. id 4118. value goes from String to obj, how do I code this part? 2. it also uses a variable string "1","2"... I can't use integer as variable, so I spelled it out? should be ok. 3. The value here is self, I can't use a variable self cause it will think it's a self property. so I just capitalized this.

I looked at this, which i believe is something similar to what i need to do, but since this is between an object and an string, im not sure what i need to code here. Swift structures: handling multiple types for a single property

2
  • var _links : _Links? must be an object rather an array. Commented Dec 14, 2019 at 16:14
  • ==> for SELF, you need to use coding keys. enum CodingKeys: String, CodingKey { case SELF = "self" } Commented Dec 14, 2019 at 16:22

2 Answers 2

4

Try this link for conversion of your json into Codable model link

    import Foundation

// MARK: - Welcome
struct Welcome: Codable {
    let metaData: [MetaDatum]
    let links: Links

    enum CodingKeys: String, CodingKey {
        case metaData = "meta_data"
        case links = "_links"
    }
}

// MARK: - Links
struct Links: Codable {
    let linksSelf, collection: [Collection]

    enum CodingKeys: String, CodingKey {
        case linksSelf = "self"
        case collection
    }
}

// MARK: - Collection
struct Collection: Codable {
    let href: String
}

// MARK: - MetaDatum
struct MetaDatum: Codable {
    let id: Int
    let key: String
    let value: ValueUnion
}

enum ValueUnion: Codable {
    case string(String)
    case valueClass(ValueClass)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode(String.self) {
            self = .string(x)
            return
        }
        if let x = try? container.decode(ValueClass.self) {
            self = .valueClass(x)
            return
        }
        throw DecodingError.typeMismatch(ValueUnion.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for ValueUnion"))
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .string(let x):
            try container.encode(x)
        case .valueClass(let x):
            try container.encode(x)
        }
    }
}

// MARK: - ValueClass
struct ValueClass: Codable {
    let the1: [String: String]

    enum CodingKeys: String, CodingKey {
        case the1 = "1"
    }
}
Sign up to request clarification or add additional context in comments.

6 Comments

very interesting link, Ill try to use it, but this uses codable when we can use decodable, is there a decodable version? i guess it doesn't matter
Swift 4 version onwards support Codable protocol so it won't be problem.
Vasu, if you want to comment to someone, prepend the @ in front of their user name, for example, do "@PranavKasetti" to comment to Pranav.
@HovercraftFullOfEels okay
this worked, thanks for the link! would had saved me so much time if I had knew this ealier
|
0

Too many unnecessary optionals, too many unnecessary underscore characters.

  1. To decode two different types an enum with associated types is reasonable.
  2. The code decodes a dictionary [String:[String:String]].
  3. To map inappropriate keys provide CodingKeys.

struct WoocomerceProduct : Decodable {
    let metaData : [Meta]
    let links : Links

    private enum CodingKeys : String, CodingKey { case metaData  = "meta_data", links = "_links" }
}

struct Meta : Decodable {
    let id : Int
    let key : String
    let value : StringOrDictionary
}

struct Links : Decodable {
    let myself : [URLType]
    let collection : [URLType]

    private enum CodingKeys : String, CodingKey { case myself  = "self", collection }
}

struct URLType : Decodable {
    let href : URL
}


enum StringOrDictionary : Decodable {
    case string(String), dictionary([String:[String:String]])

    init(from decoder : Decoder) throws
    {
        let container = try decoder.singleValueContainer()
        do {
            let stringData = try container.decode(String.self)
            self = .string(stringData)
        } catch DecodingError.typeMismatch {
            let dictionaryData = try container.decode([String:[String:String]].self)
            self = .dictionary(dictionaryData)
        }
    }
}

7 Comments

I see here, you using let, instead of var, some values in meta data can be empty, will this work even you wrote let?
let is just a declaration as constant (immutable). If keys are missing declare the corresponding struct members as optional. By the way delete the Encodableconfomance if the structs will never be encoded.
imgur.com/a/DEybvQ3 if i remove the enum, it removes the error, can i move the enum somewhere else? Also, your seeing others because thats not all the api puts out. But your code is implemented at the bottom
My answer works with the given JSON in the question. It makes no sense if the real data is completely different. I will delete my answer later.
therefore my response was imgur.com/a/Pwbpzdz, thus i didn't add it into the overall question
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.