2

using the following simplified structure:

class Property: Mappable {
    var path: String?

    override func mapping(map: Map) {
        path <- map["path"]
    }
}

class Specification {
    enum Name: String {
        case Small = "SMALL"
        case Medium = "MEDIUM"
    }
}

class ItemWithImages: Mappable {
    var properties: [Specification.Name : Property]?

    override func mapping(map: Map) {
        properties <- (map["properties"], EnumTransform<Specification.Name>())
    }
}

... with that JSON:

[{"properties: ["SMALL": {"path": "http://..."}, "MEDIUM": {"path": "http://..."}]}]

... produces when using EnumTransform() as Transform the following (reasonable) compile error:

Binary operator '<-' cannot be applied to operands of type '[Specification.Name : Property]?' and '(Map, EnumTransform<Specification.Name>)'

So how does a custom TransformType have to look like, to map that dictionary the right way?

You can find the source of EnumTransform here: https://github.com/Hearst-DD/ObjectMapper/blob/master/ObjectMapper/Transforms/EnumTransform.swift

Thanks!

mvoelkl
  • 143
  • 1
  • 10

2 Answers2

3

TransformTypes are IMHO primary designed to transform values and not keys. And your example is a little bit complicated because even value is not just basic type.

What do you think about this little hack?

struct ItemWithImages: Mappable {
    var properties: [Specification.Name : Property]?

    init?(_ map: Map) {
    }

    mutating func mapping(map: Map) {
        let stringProperties: [String: Property]?
        // map local variable
        stringProperties <- map["properties"]

        // post process local variable
        if let stringProperties = stringProperties {
            properties = [:]
            for (key, value) in stringProperties {
                if let name = Specification.Name(rawValue: key) {
                    properties?[name] = value
                }
            }
        }
    }
}
JMI
  • 2,530
  • 15
  • 26
1

We should use DictionaryTransform instead of EnumTransform. We are transforming type of Dictionary [String:Any] to [Key:Value]. In our case type is [Specification.Name: Property].

Key need to conforms protocols like Hashable, RawRepresentable, and Key.RawValue should be String.

And Value Should be conforms Mappable Protocol.

    class Property: Mappable {
        var path: String?

        override func mapping(map: Map) {
            path <- map["path"]
        }
    }

    class Specification {
        enum Name: String {
            case Small = "SMALL"
            case Medium = "MEDIUM"
        }
    }

    class ItemWithImages: Mappable {
        var properties: [Specification.Name : Property]?

        override func mapping(map: Map) {
            properties <- (map["properties"], DictionaryTransform<Specification.Name,Property>())
        }
    }
Jatin Kathrotiya
  • 539
  • 3
  • 12