I had code that was working in XCode 6 beta but stopped working recently after updating to xcode 6.1.
This is my protocol:
protocol CanDeserialiseFromJson {
class func FromJson(json : JSONValue) -> Self
}
This is implementation:
extension Invoice : CanDeserialiseFromJson {
class func FromJson(json : JSONValue) -> Self {
return Invoice()
}
}
This fails giving error:
'Invoice' is not convertable to 'Self'
As I said, this used to work and I can't work out why it doesn't anymore
Self
in a protocol is a requirement that implementations of the protocol use their own type. Since Invoice
is the type you're adopting the protocol in, your implementation of FromJson
should have a return type of Invoice
.
It's right. Your method is declared to return Self
, whereas you are returning Invoice
. Class methods are inherited, and in subclasses, Self
will be that subclass type, and Invoice
is not a subtype of that type.
To actually return Self
, assuming Invoice
has a required init()
constructor, you can do something like this:
extension Invoice : CanDeserialiseFromJson {
class func FromJson(json : JSONValue) -> Self {
return self()
}
}
In case you really need to return Self (in my case I have an Objective-C protocol that translates a method into swift function returning Self) and not mark your class as final, you need to create a required initializer and use that:
class Foo {
static func bar() -> Self {
return self.init()
}
required init() {
}
}
The final/required requirement comes from the fact that you might subclass this class and have a different initialiser.
Final removes the option for a subclass, while the required init makes sure that any subclass will implement the required initialiser used in the static method.