[英]How to deserialize NSDate with SWXMLHash
I'm using SWXMLHash and have written an extension
on NSDate
for XMLElementDeserializable.
我正在使用SWXMLHash并在
NSDate
为XMLElementDeserializable.
编写了一个extension
XMLElementDeserializable.
I've followed how the basic types are extended at the end of this file . 我已经按照如何在此文件的末尾扩展基本类型。
What I have looks like this: 我看起来像这样:
import Foundation
import SWXMLHash
struct BlogPost: XMLIndexerDeserializable {
let date: NSDate
static func deserialize(blogPost: XMLIndexer) throws -> BlogPost {
return try BlogPost(
date: blogPost["date"].value()
)
}
}
extension NSDate: XMLElementDeserializable {
/**
Attempts to deserialize XML element content to an NSDate
- element: the XMLElement to be deserialized
- throws: an XMLDeserializationError.TypeConversionFailed if the element cannot be deserialized
- returns: the deserialized NSDate value formatted as "EEE, dd MMM yyyy HH:mm:ss zzz"
*/
public static func deserialize(element: XMLElement) throws -> NSDate {
guard let dateAsString = element.text else {
throw XMLDeserializationError.NodeHasNoValue
}
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss zzz"
let date = dateFormatter.dateFromString(dateAsString)
guard let validDate = date else {
throw XMLDeserializationError.TypeConversionFailed(type: "Date", element: element)
}
return validDate
}
}
Method 'deserialize' in non-final class 'NSDate' must return 'Self' to conform to protocol 'XMLElementDeserializable'
非final类'NSDate'中的'deserialize'方法必须返回'Self'以符合协议'XMLElementDeserializable'
I've looked around SO for other answers to the same error and I haven't gleaned much information from them. 我已经环顾四周寻找同样错误的其他答案,我没有从他们那里收集到太多信息。
Any suggestions would be much appreciated. 任何建议将不胜感激。 Thanks!
谢谢!
Okay, this is pretty odd, but the problem exists because NSDate
is a class
instead of a struct
. 好吧,这很奇怪,但问题存在是因为
NSDate
是一个class
而不是struct
。 It apparently takes some work to get a class to conform to a protocol that returns self - it is far easier to get this to work with a struct! 显然需要一些工作才能让一个类符合一个返回self的协议 - 这更容易让它与一个struct一起工作!
(in Swift 4, this is unnecessary as Date
is a struct) (在Swift 4中,由于
Date
是结构,这是不必要的)
I'll have to add some additional documentation to show how this can work. 我将不得不添加一些额外的文档来说明这是如何工作的。
Check out the following code (modified from your example) to see if it works for you: 查看以下代码(从您的示例中修改)以查看它是否适合您:
import Foundation
import SWXMLHash
extension NSDate: XMLElementDeserializable {
// NOTE: for SWXMLHash 3.0 with Swift 3.0, this will be (_ element: XMLElement)
public static func deserialize(element: XMLElement) throws -> Self {
guard let dateAsString = element.text else {
throw XMLDeserializationError.NodeHasNoValue
}
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss zzz"
let date = dateFormatter.dateFromString(dateAsString)
guard let validDate = date else {
throw XMLDeserializationError.TypeConversionFailed(type: "Date", element: element)
}
// NOTE THIS
return value(validDate)
}
// AND THIS
private static func value<T>(date: NSDate) -> T {
return date as! T
}
}
let xml = "<root><elem>Monday, 23 January 2016 12:01:12 111</elem></root>"
let parser = SWXMLHash.parse(xml)
let dt: NSDate = try! parser["root"]["elem"].value()
See also Return instancetype in Swift and Using 'self' in class extension functions in Swift . 另请参见Swift中的返回instancetype和Swift 中类扩展函数中的“self” 。
NOTE : Added a comment noting that this will look slightly different for SWXMLHash 3.0. 注意 :添加了注释,注意到SWXMLHash 3.0看起来略有不同。
In case someone needs that, here is the implementation for Swift 4: 如果有人需要,这是Swift 4的实现:
extension Date: XMLElementDeserializable, XMLAttributeDeserializable {
public static func deserialize(_ element: SWXMLHash.XMLElement) throws -> Date {
guard !element.text.isEmpty else {
throw XMLDeserializationError.nodeHasNoValue
}
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = FeedParser.dateFormat
guard let date = dateFormatter.date(from: element.text) else {
throw XMLDeserializationError.typeConversionFailed(type: "Date", element: element)
}
return date
}
public static func deserialize(_ attribute: XMLAttribute) throws -> Date {
guard !attribute.text.isEmpty else {
throw XMLDeserializationError.nodeHasNoValue
}
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = FeedParser.dateFormat
guard let date = dateFormatter.date(from: attribute.text) else {
throw XMLDeserializationError.attributeDeserializationFailed(type: "Date", attribute: attribute)
}
return date
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.