【问题标题】:Convert null values to default strings in parsing JSON using JSONDecoder in Swift在 Swift 中使用 JSONDecoder 在解析 JSON 时将空值转换为默认字符串
【发布时间】:2020-06-10 20:35:06
【问题描述】:

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

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

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

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

感谢您的任何建议

【问题讨论】:

    标签: ios swift jsondecoder


    【解决方案1】:

    这可以通过手动解码来解决,如here 所述。

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

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

    这可能吸引人的另一个原因是它保留了可选值,以便您将来需要检查该值是否存在。

    【讨论】:

    • 喜欢它保留可选
    【解决方案2】:

    您可以使用自定义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"
        }
    }
    

    【讨论】:

      【解决方案3】:

      您也可以使用属性包装器来实现这一点:

      @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!
      
      }
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-01
        • 1970-01-01
        • 2014-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-09
        • 2020-10-30
        相关资源
        最近更新 更多