I'm using SWXMLHash and have written an extension on NSDate for 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'
I've looked around S.O. 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. 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!
(in Swift 4, this is unnecessary as Date is a struct)
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.
NOTE: Added a comment noting that this will look slightly different for SWXMLHash 3.0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With