在 Swift 中使用 JSON 解码器在解析 JSON 时将空值转换为默认字符串

Convert null values to default strings in parsing JSON using JSONDecoder in Swift

我正在尝试使用 JSON 解码器解析 Swift 中的一些 JSON,其中 JSON 偶尔会有空值。我想改用默认值。 以下允许我处理它,但空值稍后会导致问题。

struct Book: Codable {
        let title : String
        let author: String?
    }

有没有办法做类似的事情(以下不编译),也许使用初始化程序?:

struct Book: Codable {
        let title : String
        let author: String ?? "unknown"
    }

感谢任何建议

这可以通过手动解码解决here

另一种方法是让存储的属性准确反映数据,然后在提供非可选值的情况下计算 var。

struct Book: Codable {
    let title : String
    let author: String?

    var displayAuthor: String {
        return author ?? "unknown"
    }
}

这可能有吸引力的另一个原因是,如果您需要在将来检查该值是否存在,它会保留可选值。

您可以使用自定义 init(decoder:) 方法定义来实现此目的。如果 try 失败,请使用 decodeIfPresent API 并为 属性 提供您想要的默认值。或者您可以使用@dktaylor 提到的计算 属性 方法。这是您需要的代码:

struct Book {
    let title : String
    let author: String

    enum CodingKeys: String, CodingKey {
        case title, author
    }
}

extension Book: Codable {
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        title = try container.decode(String.self, forKey: .title)
        author = try container.decodeIfPresent(String.self, forKey: .author) ?? "unknown"
    }
}

您也可以使用 属性 包装器实现此目的:

@propertyWrapper
struct OnNil<T> {
    let value: T
    init(_ value: T) {
        self.value = value
    }

    private var _wrappedValue: T?
    var wrappedValue: T! {
        get { _wrappedValue ?? value }
        set { _wrappedValue = newValue }
    }
}

struct SomeStruct {
    let title : String

    @OnNil("unknown") 
    let author: String!

}

像这样使用 属性 包装器的好处是您不必用实用方法弄脏您的对象,也不必 fiddle 使用解码函数。缺点显然是语法看起来有点奇怪,你必须使一些变量隐式解包可选,并且由于 属性 包装器的性质,它会使你的代码稍微难以调试。