【问题标题】:How to write Swift Codable struct with Date property to Firestore如何将具有 Date 属性的 Swift Codable 结构写入 Firestore
【发布时间】:2019-10-10 21:46:55
【问题描述】:

我是 Firebase/Firestore 的新手,目前正在编写一个 iOS/Swift 应用程序来向数据库写入/读取 Customer 结构。

客户有一个validTill 类型为Date。目前,我似乎无法将此特定字段写入 Firestore,因为我认为它必须写为 Timestamp

但是我怎样才能继续使用Codable,同时仍然能够将Date 编码为Timestamp?使用Codable 扩展非常方便,因为它允许我执行customer.dictionary,并且所有内容都会自动编码并准备就绪,但是validTill 不起作用。

到目前为止,我遇到的大多数问题/答案更多是关于“解码”时间戳到日期,这与我编写的代码无关。只是编码是问题。

有什么想法可以解决这个问题吗?

extension Encodable {
  var dictionary: [String: Any]? {
    guard let data = try? JSONEncoder().encode(self) else { return nil }
    return (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)).flatMap { $0 as? [String: Any] }
  }
}


public struct Customer: Codable {  
  public var companyName :String?
  public var address     :Address
  public var contactName :String
  public var email       :String
  public var mobile      :String
  public var website     :String?
  public var validTill   :Date
    
  public init?(dictionary: [String: Any]) {
        
    guard let address = Address.init(dictionary:(dictionary["address"] as? [String:Any])!),
          let contactName = dictionary["contactName"] as? String,
          let email = dictionary["email"] as? String,
          let mobile = dictionary["mobile"] as? String,
          let validTill = dictionary["validTill"] as? Timestamp else {
            return nil
          }
  
    self.address = address
    self.contactName = contactName
    self.email = email
    self.mobile = mobile
    self.companyName = dictionary["companyName"] as? String
    self.website = dictionary["website"] as? String
    self.validTill = validTill.dateValue()
  }
    
  public init?(companyName: String?, address: Address, contactName: String, email: String, mobile: String, website: String?, validTill: Date) {
    self.companyName = companyName
    self.address = address
    self.contactName = contactName
    self.email = email
    self.mobile = mobile
    self.website = website
    self.validTill = validTill
  }
}

【问题讨论】:

  • 暂且不谈数据库和原生类型,validTill 字段一天 (2019-05-24),本地时间戳 (2019-05-24T00:12:15-08: 00) 还是祖鲁时间戳 (2019-05-24T00:00:00Z)?
  • @bsod 是的,这是一天。以 25-05-2019 为例
  • 如果只是一天,将日期作为字符串存储在数据库中(“2019-05-20”),服务器端的日期对象不会让事情变得更容易。另外,由于所有数据库都可以存储字符串,因此这使数据不可知。使用标准的 YYYY-MM-DD 格式,以便可以轻松地将字符串转换为 Swift 日期对象(如果需要)。这种格式还允许按字母数字 a-z 对字符串进行排序,从而按时间顺序对它们进行排序。因此,在客户端,您只需要获取今天的日期字符串(使用日期格式化程序)并检查 validTill 是否大于或等于,因为字符串在 YYYY-MM-DD 中。
  • 太好了,谢谢。我想我会使用字符串。不是我希望的解决方案,但现在可以解决

标签: swift firebase google-cloud-firestore timestamp codable


【解决方案1】:

您可以像这样将Date 变成Timestamp

let timestanmp = Timestamp(date: Date())

有关Timestamp 的详细信息,请参阅参考文档。

【讨论】:

    猜你喜欢
    • 2017-11-23
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 2016-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多