Swift Codable null handling

烈酒焚心 提交于 2019-12-21 04:22:20

问题


I have a struct that parse JSON using Codable.

struct Student: Codable {
    let name: String?
    let amount: Double?
    let adress: String?
}

Now if the amount value is coming as null the JSON parsing is failing.

So should I manually handle the null cases for all the Int and Double that are present in the Student struct?

The String values coming as null is automatically handled.


回答1:


Let me do this Playground for you since an example shows you more than a hundred words:

import Cocoa

struct Student: Codable {
    let name: String?
    let amount: Double?
    let adress: String?
}

let okData = """
{
   "name": "here",
 "amount": 100.0,
 "adress": "woodpecker avenue 1"
}
""".data(using: .utf8)!

let decoder = JSONDecoder()
let okStudent = try decoder.decode(Student.self, from:okData)
print(okStudent)

let nullData = """
{
   "name": "there",
 "amount": null,
"adress": "grassland 2"
}
""".data(using: .utf8)!

let nullStudent = try decoder.decode(Student.self, from:nullData)
print(nullStudent)

null is handled just fine if you define your structs using optionals. I would however advise against it if you can avoid it. Swift provides the best support I know to help me not forgetting to handle nil cases wherever they may occur, but they are still a pain in the ass.




回答2:


Was browsing through Codable and got this issue.

So to be very clear here it is, If the JSON/response would contain null as the value, its interpreted as nil. And hence for that reason one of the model's property which might contain null should be marked as optional.

For Example, consider the below JSON response,

{
"name": "Steve",
"amount": null,
"address": "India"
}

The model should be as below, cos amount is returning null.

struct Student: Codable {
    let name: String
    let amount: Double?
    let address: String
}

Suggestion: In case, if you would write a init(from decoder: Decoder) throws, always use something like below, for optional properties.

init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        amount = try values.decodeIfPresent(String.self, forKey: .amount)
        //so on...
    }

Even if you add do-catch block with try? decoder.... it can be captured if fails. Hope thats clear!! Its simple but very difficult to find the issue even if the model is containing 5 or more properties with some containing null values



来源:https://stackoverflow.com/questions/49894198/swift-codable-null-handling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!