tristanhimmelman / ObjectMapper

Simple JSON Object mapping written in Swift
MIT License
9.14k stars 1.03k forks source link

Is impossible to map top level dictionary of objects #1076

Closed krypt-lynx closed 4 years ago

krypt-lynx commented 4 years ago

Your JSON dictionary:

{
    "ISBN:0451526538": {
        "bib_key": "ISBN:0451526538", 
        "preview": "noview",
        "thumbnail_url": "https://covers.openlibrary.org/b/id/295577-S.jpg",
        "preview_url": "https://openlibrary.org/books/OL1017798M/The_adventures_of_Tom_Sawyer", 
        "info_url": "https://openlibrary.org/books/OL1017798M/The_adventures_of_Tom_Sawyer"
    }
}

api link (it's public): https://openlibrary.org/api/books?bibkeys=ISBN:0451526538&format=json

Your model:

class Book : Mappable {
    required init?(map: Map) {

    }

    func mapping(map: Map) {
        bibKey       <- map["bib_key"]
        preview      <- map["preview"]
        thumbnailUrl <- map["thumbnail_url"]
        previewUrl   <- map["preview_url"]
        infoUrl      <- map["info_url"]
    }

    var bibKey : String? = nil
    var preview : String? = nil
    var thumbnailUrl : URL? = nil
    var previewUrl : URL? = nil
    var infoUrl : URL? = nil
}

What you did:

let repo = Mapper<Dictionary<String, Book>>().map(JSONString: json) // more or less: it is behind of abstraction

What you expected:

Successful mapping

What you got:

Compile time error: Type 'Dictionary<String, Book>' does not conform to protocol 'BaseMappable'

krypt-lynx commented 4 years ago

Issue is not entirely correct, as I can see after some research. It is possible to do Mapper<Book>().mapDictionary(JSONString: <...>), but in my case I need an universal solution because of abstractions.

It looks like BaseMappable protocol should be adopted in one way or another:

extension Array : BaseMappable where Element: BaseMappable {
    // <...>
}

extension Dictionary : BaseMappable where Key == String, Value: BaseMappable {
    // <...>
}

extension Set : BaseMappable where Element: BaseMappable {
    // <...>
}
krypt-lynx commented 4 years ago

In current traversing implementation those extensions have no point: Dictionary works out of luck, other to cannot be processed.