theddnc / iModel

Validation, JSON parsing and async remote communication in one bundle.
MIT License
6 stars 0 forks source link

Not able to parse properly while a model has a property of type another model. #2

Closed Moazzam123 closed 8 years ago

Moazzam123 commented 8 years ago

I am facing another issue. While I made a property of another model in my model like this:

class model1: JsonModel {      
   dynamic var model2 : Model2?
   dynamic var obj1: String?
   dynamic var obj2: String?

 override class func jsonPropertyParsingMethods() -> [String: (AnyObject) throws -> AnyObject] {
    // we have a nested JsonModel, lets parse it
    return ["model2": Model2.fromJsonDictionary]
    }
}

In this case i found issue: Unable to find class property for provided key: "obj1". Unable to find class property for provided key: "obj2". When I checked it internally, your method:

internal static var classProperties: [String] {
    get {
        if self.classChildren != nil {
            return Array(self.classChildren!.keys)
        }
        else {
            return []
        }
    }
}

self.classChildren!.keys returning keys of model2 in this case while it is parsing properties of model1. Once self reference changes from model1 to model2, it doesn't return to model1 again to parse its data.

I think I found the issue, would you please help me in resolving it. Problem is in classChildren which is an static property and its value sets in init of model which returns internal models property while it parsed the internal model and comes back to outer model. I know I am not able to explain it clearly but if you diagnose, you will find it.

theddnc commented 8 years ago

I think I know what causes this issue - reflection results are cached in a static var, which seems to be linked with JsonModel, not its subclasses. I'll release a fix as soon as I can, probably this week.

theddnc commented 8 years ago

@Moazzam123 - I've uploaded a temporary fix. Please bump your pod version (or pull directly from github) to 0.0.5. Your nested models should parse properly. I'm not closing this issue since this patch is not very pretty (even though it's just one line) - I'll think of something better later.

Moazzam123 commented 8 years ago

Hi Thanks for update but there is a problem as you added this in setValue method: self.dynamicType.classChildren = Utils.dictionaryFromMirror(Mirror(reflecting: self))

Now it works properly for the first time but when I try to parse second time using same model, it returns nil for whole model. What I think after debugging is that before setting value, it checks whether the key is a property of this class or not in method: private class func getPropertyNameFromKey(key: String) -> String? And here it's facing the same issue.

Moazzam123 commented 8 years ago

I think I found a solution. In deinit method of Model.Swift I reset the classChildren to nil so that it will become eligible to take new array when init method of this class will call. Like this:

deinit { // set up a mirror self.dynamicType.classChildren = iModelCommon.dictionaryFromMirror(Mirror(reflecting: self))

// remove KVO for fields
for child in self.dynamicType.classChildren!.values {
    guard let label = child.label else { continue }
    self.removeObserver(self, forKeyPath: label)
}
self.dynamicType.classChildren = nil

} Please let me know if I am on a wrong track.