tristanhimmelman / ObjectMapper

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

ImmutableMappable doesn't work with optional values #1111

Closed SergeMaslyakov closed 3 years ago

SergeMaslyakov commented 3 years ago

Your JSON dictionary:

{
    "config": {
           "features": {
                 "feature1": {"enabled": true },      
                 "feature2": {"enabled": false }
           }
     }
}

Your model:

struct FeatureToggle: ImmutableMappable {

   let enabled: Bool

   init(map: Map) throws {
        self.enabled = try map.value("enabled")
    }
}

struct Features: ImmutableMappable {

   let feature1: FeatureToggle?
   let feature2: FeatureToggle?

   init(map: Map) throws {
        self.feature1 = try? map.value("feature1")
        self.feature2 = try? map.value("feature2")
    }
}

struct Config: ImmutableMappable {

   let features: Features

   init(map: Map) throws {
        self.features = try map.value("config.features")
    }
}

What you did:

let config = try Mapper<Config>().map(JSONObject: json)

What you expected:

I exepected something like:

Config(features: Features(feature1: FeatureToggle(enabled: true), feature2: FeatureToggle(enabled: false)))

What you got:

Config(features: Features(feature1: nil, feature2: nil))

When I declare properties as optional they are always nil.

I've debug and saw that it used wrong generic func:

public func value<T>(_ key: String, nested: Bool? = nil, delimiter: String = ".", file: StaticString = #file, function: StaticString = #function, line: UInt = #line) throws -> T

It works with some hack.


init(map: Map) throws {
    self.feature1 = Mapper<FeatureToggle>().map(JSON: (map.JSON["feature1"] as? [String: Any]) ?? [:])
    self.feature2 = Mapper<FeatureToggle>().map(JSON: (map.JSON["feature2"] as? [String: Any]) ?? [:])
}
SergeMaslyakov commented 3 years ago

So, I used outdated version. On the last version everything works