Reputation: 1668
I need to get some objects from REST API and map them to local objects using ObjectMapper.
These objects contain a number of enumerations. All of them are coming as integers and I want to map them to locally described enums.
To do that I have to describe standard transform function that is used by ObjectMapper.
enum Types: Int {
case Uno = 1
case Dos = 2
case Tres = 3
static var transform = TransformOf<Types,Int>(
fromJSON: {
$0 != nil
? Types(rawValue:$0!)
: nil
},
toJSON: { $0?.rawValue})
}
The problem is that I have a number of these enumerations and the function is totally same in all of them except that first argument in TransformOf<..>
list is specific for each enum.
What I want to do is to create a common protocol with default implementation of that function, something like
protocol Transformable {
var transform: TransformOf<self.Type,Int> {
get {
return TransformOf<self.Type,Int>(
fromJSON: {
$0 != nil
? Types(rawValue:$0!)
: nil
},
toJSON: { $0?.rawValue})
}
}
}
...and then to apply the protocol with the implementation to all of the enumerations I have.
Obviously reference of self.Type
is not working there and I just can't get how to generally refer to type of specific instance that will finally use the function? Probably I'm thinking wrong way of solving that problem.
Upvotes: 0
Views: 124
Reputation: 818
I think what you're missing is the Self
identifier. When implementing Generics, the Self
keyword acts as a placeholder for the type that implements your protocol. (For more information)
In other words:
protocol Transformable {
var rawValue: Int { get }
init?(rawValue: Int)
func toJSON() -> Int
static func fromJSON(rawValue: Int) -> Self?
}
Each enum
that conforms to the protocol Transformable
will then have a static method that returns its own type.
Secondly, since this is Swift 2, you can implement a protocol extension:
extension Transformable {
func toJSON() -> Int {
return self.rawValue
}
static func fromJSON(rawValue: Int) -> Self? {
return Self(rawValue: rawValue)
}
}
Now all enums that conform to the protocol will convert themselves to and from Int
:
enum Types: Int, Transformable {
case Uno = 1
case Dos = 2
case Tres = 3
//No extra implementation
}
enum OtherTypes: Int, Transformable {
case Cuatro = 4
case Cinco = 5
case Seis = 6
//No extra implementation
}
print(Types.fromJSON(1)!) //prints Uno
print(OtherTypes.fromJSON(4)!) //prints Cuatro
print(Types.fromJSON(4)!) /* throws an error, because the Types enum
does not recognise 4 as a raw value */
Upvotes: 1