Hallo,
Vorher hat diese Bibliothek nur Daten transformiert, ohne eine Datumstransformationsfunktion angeben zu müssen (zumindest ist dies das Verhalten, das ich gesehen habe).
Also zum Beispiel
public private(set) var myDate:Date?
public fund mapping(map: Map) {
myDate <- map["my_date"]
}
Da das Datum das Format "2016-12-09T13:37:27.262Z" hat, würde es dieses Datum richtig umwandeln, ohne dass ich angeben müsste, dass es sich tatsächlich um ein Datum handelt.
Mein aktuelles Modell kann das Datum aus irgendeinem Grund nicht richtig analysieren. Ich habe beide Beispiele in der Readme-Datei ausprobiert, ich habe mir die "geschlossenen" Probleme bezüglich der Datumsformatierung angesehen und ich habe auch versucht, ihre Beispiele zu verwenden ... immer noch kein Glück.
Ich habe diese Datumstransformationen ausprobiert
Mein Unit-Test...
class TripTests: XCTestCase {
func testInflateTestObjectFromJSON() {
var tripObj = [String:AnyObject]()
tripObj["_id"] = "123" as AnyObject?
tripObj["dropoff_time"] = "2016-12-09T13:37:27.262Z" as AnyObject?
let trip = Trip(JSON: tripObj)
XCTAssertNotNil(trip?.id)
XCTAssertNotNil(trip?.dropoffTime)
print(trip?.pickupTime)
print(trip?.dropoffTime)
dump(trip?.toJSONString())
}
}
was produziert...
Optional(1970-01-01 00:33:36 +0000)
Optional(1970-01-01 00:33:36 +0000)
▿ Optional("{\"dropoff_time\":2016,\"pickup_time\":2016,\"_id\":\"123\"}")
Offensichtlich ist das Datum, das ich angebe, nicht 1970 ... und das obige Datum ist tatsächlich ein ISO-formatiertes Datum. Der Server, den ich betreibe, ist Express/Mongo und ich verwende einfach den JavaScript-Aufruf Date.now, um ein Datum zu generieren. Außerdem ist das Schema im Mongo-Modell vom Typ 'Datum'.
Hier ist mein Trip-Modell
import Foundation
import ObjectMapper
public class Trip : Mappable {
public private(set) var id: String?
public var pickupTime:Date?
public var dropoffTime:Date?
public var completed:Bool?
public private(set) var createdAt:Date?
public private(set) var updatedAt:Date?
public init(captain: User?, passenger: User?) {
self.captain = captain
self.passenger = passenger
}
public required init?(map: Map) {
}
public func mapping(map: Map) {
id <- map["_id"]
pickupTime <- (map["pickup_time"], DateTransform())
dropoffTime <- (map["dropoff_time"], DateTransform())
completed <- map["completed"]
updatedAt <- (map["updated_at"], DateTransform())
createdAt <- (map["created_at"], DateTransform())
}
}
Auch hier habe ich, wie oben erwähnt, versucht, sowohl DateTransform() als auch ISO8601DateTransform() zu verwenden.
Wenn ich die DateTransform-Funktion verwende, wird mein Komponententest "bestanden", da die Datumseigenschaft nicht mehr Null ist, jedoch das Datum von 1970 ist, das nicht korrekt ist.
Wenn ich ISO8601DateTransform verwende, ist die Eigenschaft nil und der Komponententest schlägt fehl, da erwartet wurde, dass das Datum nicht nil ist.
Vorher würde ich nur angeben, dass die Eigenschaft ein "Datum" ist und alles korrekt transformiert wird, ohne dass ich speziell ein DateTransform-Tupel für die Zuordnung festlegen muss. Ich weiß nicht genau was ich hier falsch mache.
==== Aktualisiert, damit es schöner aussieht =====
Also ich glaube, ich habe mein Problem vielleicht selbst gelöst...
Ich weiß immer noch nicht, warum der eingebaute ISO-Datumsformatierer nicht funktioniert, aber ich habe meinen eigenen erstellt
import Foundation
import ObjectMapper
open class ISODateTransform: TransformType {
public typealias Object = Date
public typealias JSON = String
public init() {}
public func transformFromJSON(_ value: Any?) -> Date? {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
guard let strValue = value as? String else { return nil }
return formatter.date(from: strValue)
}
public func transformToJSON(_ value: Date?) -> String? {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
guard value != nil else { return nil }
return formatter.string(from: value!)
}}
dies scheint gut zu funktionieren, Unit-Tests werden jetzt mit gültigen Daten durchgeführt.
Nur um dies zu ergänzen. Ich konnte die obige Lösung nicht zum Laufen bringen, aber sie hat mich in die richtigen Richtungen gelenkt, die so sehr geschätzt werden. Ich habe einige Optimierungen vorgenommen und das funktioniert für mich.
//
// ISODateTransform.swift
//
import Foundation
import ObjectMapper
open class ISODateTransform: TransformType {
public typealias Object = Date
public typealias JSON = String
public init() {}
public func transformFromJSON (_ value: Any?) -> Date? {
guard let datestring = value as? String else { return nil }
let isoFormatter = ISO8601DateFormatter()
let date = isoFormatter.date(from: datestring)!
return date
}
public func transformToJSON(_ value: Date?) -> String? {
let isoFormatter = ISO8601DateFormatter()
let string = isoFormatter.string(from: value!)
return string
}
}
Ein weiterer Fix:
https://forums.swift.org/t/iso8601dateformatter-fails-to-parse-a-valid-iso-8601-date/22999/12
offene Klasse ISODateTransform: TransformType {
public typealias Object = Date
öffentlicher Typalias JSON = String
public init() {}
public func transformFromJSON (_ value: Any?) -> Date? {
guard let datestring = value as? String else { return nil }
let isoFormatter = ISO8601DateFormatter()
//Critical Fix
isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let date = isoFormatter.date(from: datestring)!
return date
}
public func transformToJSON(_ value: Date?) -> String? {
let isoFormatter = ISO8601DateFormatter()
//Critical Fix
isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let string = isoFormatter.string(from: value!)
return string
}
}
Hilfreichster Kommentar
Also ich glaube, ich habe mein Problem vielleicht selbst gelöst...
Ich weiß immer noch nicht, warum der eingebaute ISO-Datumsformatierer nicht funktioniert, aber ich habe meinen eigenen erstellt
dies scheint gut zu funktionieren, Unit-Tests werden jetzt mit gültigen Daten durchgeführt.