Swift 4 JSON Decodable simplest way to decode type change

后端 未结 8 2064
天涯浪人
天涯浪人 2020-12-01 05:47

With Swift 4\'s Codable protocol there\'s a great level of under the hood date and data conversion strategies.

Given the JSON:

{
    \"name\": \"Bob\         


        
8条回答
  •  广开言路
    2020-12-01 06:05

    The options above only deal with the situation that the given field is always String. Many times I've met APIs where the output was once a string, other times number. So this is my suggestion to solve this. It is up to you to alter this to throw exception or set the decoded value to nil.

    var json = """
    {
    "title": "Apple",
    "id": "20"
    }
    """;
    var jsonWithInt = """
    {
    "title": "Apple",
    "id": 20
    }
    """;
    
    struct DecodableNumberFromStringToo: Decodable {
        var value: T
        init(from decoder: Decoder) {
            print("Decoding")
            if let container = try? decoder.singleValueContainer() {
                if let val = try? container.decode(T.self) {
                    value = val
                    return
                }
    
                if let str = try? container.decode(String.self) {
                    value = T.init(str) ?? T.zero
                    return
                }
    
            }
            value = T.zero
        }
    }
    
    
    struct MyData: Decodable {
        let title: String
        let _id: DecodableNumberFromStringToo
    
        enum CodingKeys: String, CodingKey {
            case title, _id = "id"
        }
    
        var id: Int {
            return _id.value
        }
    }
    
    do {
        let parsedJson = try JSONDecoder().decode(MyData.self, from: json.data(using: .utf8)!)
    
        print(parsedJson.id)
    
    } catch {
        print(error as? DecodingError)
    }
    
    
    do {
        let parsedJson = try JSONDecoder().decode(MyData.self, from: jsonWithInt.data(using: .utf8)!)
    
        print(parsedJson.id)
    
    } catch {
        print(error as? DecodingError)
    }
    

提交回复
热议问题