0

I'm trying to use an operator to parse a JSON into an object that conforms with the protocol mappable.

First I have a class called Map that is which it's function is store the current key it's being parsed and the complete JSON to parse and the current value to be stored

private class Map {
    var json: [String : Any]?
    var key: String!
    convenience init(json: [String : Any]?) {
        self.init()
        self.json = json
    }

    public var currentValue: Any? {
        get{
            guard let key = key, let json = json else {
                return nil
            }
            return json[key]
        }
    }

    public subscript(key: String) -> Map {
        // save key and value associated to it
        self.key = key
        return self
    }
}

Then I have an operator that get the current value on the rhs based on the Map.Key and passes it to the lhs, and here lies the problem if the lhs is an Array with an object that follows the protocol Mappable, it should use the the operator recursively, until end parsing.

The problem is: the comparison lhs is Array always returns false, so I can't typecast it to do the necessary iteration to parse it. (commented lines).

Any ideas how to approach the problem?

infix operator <<< // JSON to object


private func <<< <T: Any>(lhs: inout T, rhs: Map) {

    if let rhsArray = rhs.currentValue as? Array<Dictionary<String, Any>>{
        print(type(of: lhs)) // <Array<(Book in *someHash*)>>
        debugPrint(lhs is Array<Mappable>) // false

        var rhsReturnArray: Array<Mappable> = []
        for currentRHSValue in rhsArray {
//            let object = T.Element.self.from(Map(json: currentRHSValue))
//            rhsReturnArray.append(object)
        }
        // Do something
    }
    else if let value = rhs.currentValue as? T{
        lhs = value
    }
}




private class Autor: Mappable {
    var books: [Book]?

    func from(map: Map) -> Bool {
        books <<< map["Books"]
        return true
    }
}

private class Book: Mappable {


    var title: String?
    var numberOfPages: Int?
    func from(map: Map) -> Bool {
        title <<< map["Title"]
        numberOfPages <<< map["Number of Pages"]
        return true
    }
}


let someDictionary = ["Books" : [["Title": "Happy Potter", "Number of Pages": 420], ["Title": "Happy Potter2", "Number of Pages": 422]]]

private let autor = Autor()
autor.from(map: Map(json: someDictionary))

print(autor.books?.first)

And I can't use third part frameworks on this project.

RodolfoAntonici
  • 1,555
  • 21
  • 34
  • Did you confirm the type of `T` ? It looks like `Optional` to me. – mmtootmm Feb 06 '17 at 19:03
  • Yes I did and it's an Optional, but I can't compare it to Array? – RodolfoAntonici Feb 06 '17 at 19:16
  • Yes you can't. Because `Optional` is just an `emum` type. Some workarounds for using Generics with `Optional` type could be found on StackOverflow: http://stackoverflow.com/questions/25064644/how-to-determine-if-a-generic-is-an-optional-in-swift – mmtootmm Feb 06 '17 at 20:20
  • Oh, thank you, the only workaround I've managed to do is an overload, changing the T expected object to an optional array, dictionary, etc – RodolfoAntonici Feb 07 '17 at 11:00

0 Answers0