litebrite litebrite - 2 months ago 15
Swift Question

Swift error when using generic parameter

I'm trying to use generics to simplify some XML deserialization, however, Swift 2.0 is choking saying that I'm not using the generic in my method signature. I'm confused as to why it is throwing this error since I'm directly instantiating the class type passed in. Any suggestions as to the cause of this error? The exact error is :

Generic parameter 'T' is not used in function signature


MTXMLDeserializable is the base class I'm using and has the method:
init(properties: Dictionary<String, String>?, propertyMap: Dictionary<String, String>?)


Here is the offending method:

func transformResponse<T: MTXMLDeserializable>(responseData: XMLIndexer?) -> [MTXMLDeserializable]? {
if let data = responseData {
let properties = data["body"].children
return properties.map {
(xmlProps) -> MTXMLDeserializable in
let objProps = xmlProps.element!.attributes
return (T.self as T.Type).init(properties: objProps, propertyMap: self.propertyMap)
}
} else {
return .None
}


Thinking that it may be choking on using the generic inside of the closure passed to
properties.map
I rewrote the method like so:

func transformResponse<T: MTXMLDeserializable>(responseData: XMLIndexer?) -> [MTXMLDeserializable]? {
if let data = responseData {
let properties = data["body"].children
let objs = NSMutableArray()
for xmlProps in properties {
let objProps = xmlProps.element!.attributes
let obj = (T.self as T.Type).init(properties: objProps, propertyMap: self.propertyMap)
objs.addObject(obj)
}
return objs as! NSArray
} else {
return .None
}


Even switching from
(T.self as T.Type).init(properties: objProps, propertyMap: self.propertyMap)
to just using
T(properties: objProps, propertyMap: self.propertyMap)
doesn't fix the issue.

I've done battle with the swift compiler over this and upgraded to Swift 2.0 hoping I can get around this issue with limited success (in Swift 1.2 it crashed the compiler, at least now it throws an error instead).

I could have subclasses of this class pass their own closure for instantiating the type they are expecting and ditch using a generic for this, but I think this is nice and clean and saves writing all those overridden methods.

Thanks for taking a look and any help is appreciated!

Answer Source

You use generic T but you do not use it anywhere in the method body. That's what the error is about.

E.g. it probably should look like:

func transformResponse<T: MTXMLDeserializable>(responseData: XMLIndexer?) -> [T]? {
    if let data = responseData {
        let properties = data["body"].children
        return properties.map {
            (xmlProps) -> T in
            let objProps = xmlProps.element!.attributes
            return (T.self as T.Type).init(properties: objProps, propertyMap: self.propertyMap)
        }
    } else {
        return .None
}