Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
259 views
in Technique[技术] by (71.8m points)

Swift 4 JSON Decodable with multidimensional and multitype array

{
"values":[
[1,1,7,"Azuan Child","Anak Azuan","12345","ACTIVE","Morning",7,12,"2017-11-09 19:45:00"],
[28,1,0,"Azuan Child2","Amran","123456","ACTIVE","Evening",1,29,"2017-11-09 19:45:00"]
]
}

Ok, this is my json format that i received from the server

Right now i want to decode it into my struct but still have no luck on it.

struct ChildrenTable: Decodable {
    var values: [[String]]?
}

And my caller method on URLSession look like this

URLSession.shared.dataTask(with: request) { (data, response, err) in
        guard let data = data else { return }

        let dataAsString = String(data: data, encoding: .utf8)
        print(dataAsString)

        do {
            let children  = try
                JSONDecoder().decode(ChildrenTable.self, from: data)
                print (children)
        } catch let jsonErr {
            print ("Error serializing json: ", jsonErr)
        }
    }.resume()

And the error that i got are

Error serializing json:  
typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [Vito_Parent.ChildrenTable.(CodingKeys in _1B826CD7D9609504747BED0EC0B7D3B5).values, Foundation.(_JSONKey in _12768CA107A31EF2DCE034FD75B541C9)(stringValue: "Index 0", intValue: Optional(0)), 
Foundation.(_JSONKey in _12768CA107A31EF2DCE034FD75B541C9)(stringValue: "Index 0", intValue: Optional(0))], 
debugDescription: "Expected to decode String but found a number instead.", underlyingError: nil))

I know there's an int in the array and i only cast String for the values var values: [[String]]? ( the reason why this error popup), but i simply cannot use any multidimensional array or tuples in my structs since it follow the protocol of Decodable.

I also cannot convert the data into dictionary since it will throw error "Expected to decode Dictionary but found array instead"

Any ideas on solving this problem? i tried casting string type on data but still no luck...

p/s: if all the json format are in string type, there would be no problem, but i dont have the permission on changing that since i call it from API.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As you said, your json array is multi-type but you are trying to decode all into String. Default conformance of String to Decodable does not allow that. The only solution comes into my mind is to introduce new type.

struct IntegerOrString: Decodable {
    var value: Any

    init(from decoder: Decoder) throws {
        if let int = try? Int(from: decoder) {
            value = int
            return
        }

        value = try String(from: decoder)
    }
}

struct ChildrenTable: Decodable {
    var values: [[IntegerOrString]]?
}

Run online


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...