使用 Swift 4 中的 JSONDecoder,缺少的键可以使用默认值而不是可选属性吗? [英] With JSONDecoder in Swift 4, can missing keys use a default value instead of having to be optional properties?

查看:28
本文介绍了使用 Swift 4 中的 JSONDecoder,缺少的键可以使用默认值而不是可选属性吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Swift 4 添加了新的 Codable 协议.当我使用 JSONDecoder 时,它似乎要求我的 Codable 类的所有非可选属性在 JSON 中有键,否则会引发错误.

Swift 4 added the new Codable protocol. When I use JSONDecoder it seems to require all the non-optional properties of my Codable class to have keys in the JSON or it throws an error.

让我的类的每个属性都是可选的似乎是不必要的麻烦,因为我真正想要的是使用 json 中的值或默认值.(我不希望该属性为零.)

Making every property of my class optional seems like an unnecessary hassle since what I really want is to use the value in the json or a default value. (I don't want the property to be nil.)

有没有办法做到这一点?

Is there a way to do this?

class MyCodable: Codable {
    var name: String = "Default Appleseed"
}

func load(input: String) {
    do {
        if let data = input.data(using: .utf8) {
            let result = try JSONDecoder().decode(MyCodable.self, from: data)
            print("name: (result.name)")
        }
    } catch  {
        print("error: (error)")
        // `Error message: "Key not found when expecting non-optional type
        // String for coding key "name""`
    }
}

let goodInput = "{"name": "Jonny Appleseed" }"
let badInput = "{}"
load(input: goodInput) // works, `name` is Jonny Applessed
load(input: badInput) // breaks, `name` required since property is non-optional

推荐答案

我更喜欢的方法是使用所谓的 DTO - 数据传输对象.它是一个结构,符合 Codable 并表示所需的对象.

Approach that I prefer is using so called DTOs - data transfer object. It is a struct, that conforms to Codable and represents the desired object.

struct MyClassDTO: Codable {
    let items: [String]?
    let otherVar: Int?
}

然后,您只需使用该 DTO 初始化您想在应用程序中使用的对象.

Then you simply init the object that you want to use in the app with that DTO.

 class MyClass {
    let items: [String]
    var otherVar = 3
    init(_ dto: MyClassDTO) {
        items = dto.items ?? [String]()
        otherVar = dto.otherVar ?? 3
    }

    var dto: MyClassDTO {
        return MyClassDTO(items: items, otherVar: otherVar)
    }
}

这种方法也很好,因为您可以根据需要重命名和更改最终对象.与手动解码相比,它很清晰并且需要更少的代码.此外,通过这种方法,您可以将网络层与其他应用程序分开.

This approach is also good since you can rename and change final object however you wish to. It is clear and requires less code than manual decoding. Moreover, with this approach you can separate networking layer from other app.

这篇关于使用 Swift 4 中的 JSONDecoder,缺少的键可以使用默认值而不是可选属性吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆