【问题标题】:Swift and ObjectMapper: NSDate with min valueSwift 和 ObjectMapper:具有最小值的 NSDate
【发布时间】:2016-12-04 17:30:31
【问题描述】:

我正在使用ObjectMapper 将 json 转换为对象。我的问题是 NSDate 属性未正确映射。这是json:

{
   "Id":4775,
   "Cor":{
      "Id":2,
      "Nome":"Amarelo",
      "HTMLCode":"FFFB00"
   },
   "Data":"2016-07-25T09:35:00",
   "Texto":"test test test",
   "Kilometro":547.0
}

这是我的可映射类

class RoadWarning : Mappable {

    var id: Int?
    var color: RoadWarningColor?
    var date: NSDate?
    var text: String?
    var kilometer: Float?

    required init?(_ map: Map){

    }

    func mapping(map: Map) {
        id <- map["Id"]
        color <- map["Cor"]
        text <- map["Texto"]
        kilometer <- map["Kilometro"]
        date    <- (map["Data"], DateTransform())
    }
}

问题是日期属性始终是 1970-01-01。我还看不到我错过了什么。你能看出这个映射有什么问题吗?

谢谢

【问题讨论】:

    标签: swift objectmapper


    【解决方案1】:

    ObjectMapper 不能正确地从 String 转换为 NSDate 你必须做出这样的解决方法来指定它需要从 String 转换的 NSDate 格式的类型:

    func mapping(map: Map) {
        id <- map["Id"]
        color <- map["Cor"]
        text <- map["Texto"]
        kilometer <- map["Kilometro"]
    
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
    
        if let dateString = map["Data"].currentValue as? String, let _date = dateFormatter.dateFromString(dateString) {
            date = _date
        } 
    }
    

    希望对你有所帮助。

    【讨论】:

    • 谢谢!它做了。我只需要更改这一行 dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
    • 这不是一个好方法,转换是正确设置数据的正确方法。内置的 DateTransform 使用 timeIntervalSince1970 因此不适用于格式化的日期。最好的方法是创建自己的 DateTransform,就像 Rodolfo 在下面所做的那样。
    • @Leon 首先,让我澄清一下你提到的DateTransform 使用timeIntervalSince1970。协议TransformType 是一个创建转换的协议,如何实现transformToJSON(_:)transformFromJSON(_:) 完全取决于您。如果您仔细查看下面的代码,它与我上面为从 JSON 转换为 Date 所做的完全一样,这就是问题的目标。因此,如果您当然是,请在否决一个没有争论的问题之前小心。
    • 如果您需要从多个地方解析到Date,您可以使用它进行转换,但这并不意味着您不能将行为封装在一个函数中并使用它。一切都取决于您使用它的上下文,因为您每次都必须为转换实现transformToJSON,即使您返回nil,也许您永远不会在您的应用程序中创建JSON。我不会对解决方案投反对票,因为我认为另一种解决方案比另一种解决方案有更好的方法,我不在乎你的反对意见,所以需要开始跟踪它,以与有目的的喜欢你的人争论。
    • 我对您的回答投了反对票,因为我认为这不是一个好方法,这就是投票系统的全部意义所在。您不需要亲自处理。
    【解决方案2】:

    您可以只创建一个允许 dateFormat 作为参数的 TransformType 类:

    //  DateFormatTransform.swift
    
        import Foundation
        import ObjectMapper
        public class DateFormatTransform: TransformType {
            public typealias Object = NSDate
            public typealias JSON = String
    
    
        var dateFormat = NSDateFormatter(dateFormat: "yyyy-MM-dd HH:mm:ss")
    
        convenience init(dateFormat: String) {
            self.init()
            self.dateFormat = NSDateFormatter(dateFormat: dateFormat)
        }
    
        public func transformFromJSON(value: AnyObject?) -> Object? {
            if let dateString = value as? String {
                return self.dateFormat.dateFromString(dateString)
            }
            return nil
        }
        public func transformToJSON(value: NSDate?) -> JSON? {
            if let date = value {
                return self.dateFormat.stringFromDate(date)
            }
            return nil
        }
    }
    

    并像这样使用它:

    func mapping(map: Map) {
        id <- map["Id"]
        color <- map["Cor"]
        text <- map["Texto"]
        kilometer <- map["Kilometro"]
        date    <- (map["Data"], DateFormatTransform(dateFormat: "yyyy-MM-dd"))
    }
    

    【讨论】:

    • 顺便说一下,我做了一个要点DateFormatTransform.swift
    • 你能更新你的代码以获得最新的 Swift 版本吗?谢谢!
    • 当我像这样使用 Mapper().mapArray(JSONString: str) 我想在这个地方使用自定义转换时如何使用自定义转换
    • @TàTruhoada 在 Swift 4 中你有 Codable 协议,这样做更容易。
    • @DeepakrajMurugesan 请创建一个包含更多上下文的堆栈溢出问题。
    【解决方案3】:

    RodolfoAntonici 使用 SwiftDate 库重写为 Swift 4 的答案

    import SwiftDate
    import Foundation
    import ObjectMapper
    public class DateFormatTransform: TransformType {
        public typealias Object = Date
        public typealias JSON = String
    
    
        public func transformFromJSON(_ value: Any?) -> Object? {
            if let dateString = value as? String {
                return dateString.toDate()?.date
            }
            return nil
        }
        public func transformToJSON(_ value: Date?) -> JSON? {
            if let date = value {
                return date.toString()
            }
            return nil
        }
    }
    

    【讨论】:

      【解决方案4】:
      import Foundation
      import ObjectMapper
      
      public class DateFormatTransform: TransformType {
          public typealias Object = Date
          public typealias JSON = Double
      
          var dateFormat = DateFormatter()
      
          convenience init(_ format: String) {
              self.init()
              self.dateFormat.dateFormat = format
          }
      
          open func transformFromJSON(_ value: Any?) -> Date? {
              if let timeInt = value as? Double {
                  return Date(timeIntervalSince1970: TimeInterval(timeInt))
              }
      
              if let timeStr = value as? String {
                  return self.dateFormat.date(from: timeStr)
              }
      
              return nil
          }
      
          open func transformToJSON(_ value: Date?) -> Double? {
              if let date = value {
                  return Double(date.timeIntervalSince1970)
              }
              return nil
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多