Swift 和 ObjectMapper:具有最小值的 NSDate
Posted
技术标签:
【中文标题】Swift 和 ObjectMapper:具有最小值的 NSDate【英文标题】:Swift and ObjectMapper: NSDate with min value 【发布时间】: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。我还看不到我错过了什么。你能看出这个映射有什么问题吗?
谢谢
【问题讨论】:
【参考方案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 版本吗?谢谢! 当我像这样使用 MapperRodolfoAntonici 使用 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
【讨论】:
以上是关于Swift 和 ObjectMapper:具有最小值的 NSDate的主要内容,如果未能解决你的问题,请参考以下文章
Swift 3 的 ObjectMapper 和 Alamofire 问题 Alamofire 4 的 Alamofire 版本
Swift - 嵌套对象的映射 (Objectmapper)
Swift/Alamofire/ObjectMapper:忽略零值