EVReflection icon indicating copy to clipboard operation
EVReflection copied to clipboard

Still having an retrieving objects from a initialized nested arrays.

Open noobs2ninjas opened this issue 8 years ago • 3 comments
trafficstars

I tried to reply to the old issue I had which had already been closed. I wish I hadnt been busy so I could have tested and replied to weather or not the issue had been fixed.

So, initializing a nested array has never really been initializing.

Specifically its when I try to access the data I get "fatal error: NSArray element failed to match the Swift Array Element type" on something like. let dataModel = data[0][0][0]

Inspecting the data has on crash..the first nested array looks fine. Its the arrays inside that, that remain "_NSDictionaryM *".

In otherwords I see [0] = ([[App.MyDataModel])) -> [0] = ([App.MyDataModel]) -> [0] = (_NSDictionaryM *)

noobs2ninjas avatar Jun 12 '17 23:06 noobs2ninjas

I will give it another look...

evermeer avatar Jun 13 '17 06:06 evermeer

On request here the workaround: You have to create a propertyConverter for that property. the decodeConverter will be called with an [[NSDictionary]]. In version 5.6.0 I added helper functions to convert it to [[YourObject]]. The code (from the unit tests) will look something like this:

class A81b: EVObject {
    var array: [[A81]] = [[]]
    
    override func propertyConverters() -> [(key: String, decodeConverter: ((Any?) -> ()), encodeConverter: (() -> Any?))] {
        return [(key: "array",
            decodeConverter: {
                self.array = ($0 as? NSArray)?.nestedArrayMap { A81(dictionary: $0) } ?? [[]]
        }, encodeConverter: { return self.array })]
    }
}

class A81c: EVObject {
    var array: [[[A81]]] = [[[]]]

    override func propertyConverters() -> [(key: String, decodeConverter: ((Any?) -> ()), encodeConverter: (() -> Any?))] {
        return [(key: "array",
                 decodeConverter: {
                    self.array = ($0 as? NSArray)?.doubleNestedArrayMap { A81(dictionary: $0) } ?? [[]]
        }, encodeConverter: { return self.array })]
    }
}

class A81d: EVObject {
    // Skipping the triple, quadruple, quintuple nestedArrayMap and go strait to the sextuple
    // You should not want something like this
    var array: [[[[[[[A81]]]]]]] = [[[[[[[]]]]]]]
    
    override func propertyConverters() -> [(key: String, decodeConverter: ((Any?) -> ()), encodeConverter: (() -> Any?))] {
        return [(key: "array",
                 decodeConverter: {
                    self.array = ($0 as? NSArray)?.sextupleNestedArrayMap { A81(dictionary: $0) } ?? [[[[[[]]]]]]
        }, encodeConverter: { return self.array })]
    }
}

class A81: EVObject {
    var openId: String = ""
}

evermeer avatar Apr 05 '18 06:04 evermeer

Fyi, this fails for eg [[Double]], because Double doesn't get deserialized to an NSDictionary. Until something's fixed/changed, y'all, you can use some form of the following in the decodeConverter, taken from the definition nestedArrayMap:

                self.array = (($0 as? NSArray)?.map {
                    (($0 as? NSArray)?.map {
                        $0 as? Double ?? 0.0
                        }) ?? []
                })

Erhannis avatar Jul 19 '19 21:07 Erhannis