【问题标题】:Optional list of NSData in Realm - SwiftRealm 中的可选 NSData 列表 - Swift
【发布时间】:2020-05-07 23:20:50
【问题描述】:

我需要在 Realm 中将图像列表保存为 NSData。我尝试使用 Realm 可选,但 realmOptional<NSdata> 无法使用,因为 realmOptional 不符合 NSDate 类型。
有办法吗?

编辑:基本上我想要的是能够存储 NSData 列表,但可选 类似:

@objc dynamic var photos: List<NSData>?

【问题讨论】:

  • 这能回答你的问题吗? How to put an image in a Realm database?
  • 感谢您的回答,我的问题是如何在领域中存储可选的数据数组
  • 为什么需要可选列表?它只是一个List,它代表一个对多的关系,如果你不存储任何东西,它的计数为0,不占用空间。你能用一些代码阐明用例吗?
  • @jay 假设您正在解码,但您无法确定返回的 JSON 是否包含项目数组(或列表)。我们需要以某种方式使其成为可选。
  • @user139816 请参阅updated documentation 了解列表类型(注意可选列)。数组和列表,虽然它们具有相似的功能,但它们是非常不同的选项。列表表示前向关系,而数组是“对象内”的一组对象。

标签: ios swift database realm


【解决方案1】:

根据https://realm.io/docs/swift/latest/#property-cheatsheet,您不能在领域中定义可选列表

【讨论】:

    【解决方案2】:

    使用 Decodable 时可选 List 类型的解决方案

    在我的情况下,我需要一个可选的List,因为我正在将 json 解码为 Realm 对象,并且该属性可能不存在于 json 数据中。典型的解决方法是手动解码并使用decodeIfPresent()。这并不理想,因为它需要模型中的样板代码:

    class Driver: Object, Decodable {
        var vehicles = List<Vehicle>()
        var name: String = ""
        // etc
    
        public required init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.vehicles = try container.decodeIfPresent(List<Vehicle>.self, forKey: .vehicles) ?? List<Vehicle>()
            self.name = try container.decode(String.self, forKey: .name)
            // etc
        }
    }
    

    但是,我们可以通过扩展 KeyedDecodingContainer 并为 List 类型提供重载来避免样板。这将强制使用decodeIfPresent() 解码所有列表:

    • 领域 v5:

      class Driver: Object, Decodable {
          var vehicles = List<Vehicle>()
          var name: String = ""
          //etc
      }
      
      class Vehicle: Object, Decodable {
          var drivers = List<Driver>()
          var make: String = ""
          // etc
      }
      
      extension KeyedDecodingContainer {
          // This will be called when any List<> is decoded
          func decode<T: Decodable>(_ type: List<T>.Type, forKey key: Key) throws -> List<T> {
            // Use decode if present, falling back to an empty list
              try decodeIfPresent(type, forKey: key) ?? List<T>()
          }
      }
      
    • 境界 v10+:

      class Driver: Object, Decodable {
          @Persisted var vehicles: List<Vehicle>
          @Persisted var name: String = ""
          // etc
      }
      
      class Vehicle: Object, Decodable {
          @Persisted var drivers: List<Driver>
          @Persisted var make: String = ""
          // etc
      }
      
      extension KeyedDecodingContainer {
          // This will be called when any @Persisted List<> is decoded
          func decode<T: Decodable>(_ type: Persisted<List<T>>.Type, forKey key: Key) throws -> Persisted<List<T>> {
              // Use decode if present, falling back to an empty list
              try decodeIfPresent(type, forKey: key) ?? Persisted<List<T>>(wrappedValue: List<T>())
          }
      }
      

    编辑:澄清代码示例,修正错字

    【讨论】:

      猜你喜欢
      • 2020-08-27
      • 2017-10-27
      • 2017-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-11
      相关资源
      最近更新 更多