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
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()
}
}
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
.
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.
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