I have encountered a problem with deserialization of my DateTime strings from JSON in swift.
I have entity containing multiple NSDate values (which are received from .NET WebAPI server). My problem is that some of JSON properties contain date strings formatted like this: "yyyy-MM-ddTHH:mm:ss"
and some have miliseconds contained, like this: "yyyy-MM-ddTHH:mm:ss.SSS"
In entity initializer there is statement selecting my NSDateFormatter (without it none of date strings is getting deserialised):
EVReflection.setDateFormatter(NSDateFormatter.isoDateFormatter())
and isoDateFormatter
looks like this:
class func isoDateFormatter() -> NSDateFormatter {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss"
formatter.locale = NSLocale.currentLocale()
return formatter
}
After my entity is mapped into an object, NSDate
properties containing miliseconds were not mapped to object leaving those properties nil
while properties without miliseconds are mapped
Example:
{
"startTime" : "2018-10-05T10:15:00", // is deserialized
"startTrackingTime" : "2018-10-05T10:14:59.637" // is not deserialized
}
What I want to accomplish is just to deserialize all date strings into NSDate properties, I even dont need milliseconds part but i don't know how to tell the EVReflection to use more than one NSDateFormatter or more than one date-time format or to just ignore milliseconds part.
EDIT: I can't use NSISO8601DateFormatter because it does not support iOS 9, only iOS 10+
The only solution for this situation I have found is defining custom property converter for properties with different Date format.
This is example of one custom property converter I have used.
key: "startTrackingTime",
decodeConverter: {
let formatter = NSDateFormatter.isoMilisecondsDateFormatter()
self.startTrackingTime = formatter.dateFromString($0 as! String)
},
encodeConverter: {
let formatter = NSDateFormatter.isoMilisecondsDateFormatter()
if self.startTrackingTime != nil {
return formatter.stringFromDate(self.startTrackingTime!)
} else {
return ""
}
}
Where isoMilisecondsFormatter()
is
class func isoMilisecondsDateFormatter() -> NSDateFormatter {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSS"
formatter.timeZone = NSTimeZone(abbreviation: "UTC")
formatter.locale = NSLocale.currentLocale()
return formatter
}
So, I had to specify exact formatter for each property that is not received in (let's say) "default" format which seems as a really hacky way to do it, but I did not know better.
If someone has better solution I would appreciate sharing it with others.