swift - ObjectMapper how to map different object based on JSON -
i'm using objectmapper (https://github.com/hearst-dd/objectmapper) map json swift objects.
say have json structure:
{ animals: [ { "type": "cat", "weight": 23, "catchmice": true }, { "type": "fish", "weight": 1, "swim": true } ] }
i have following swift objects:
class foo: mappable { var animals: [animal] = [] func mapping(map: map) { animals <- map["animals"] //but want able distinguish between cat , fish objects here } } class animal: mappable { var type: string? var weight: double? required init?(map: map) {} func mapping(map: map) { type <- map["type"] weight <- map["weight"] } } class cat: animal { // how make use of class var catchmice: bool? } class fish: animal { // how make use of class var swim: bool? }
how can distinguish between cat
, fish
in mapping using type
key in json objects? much!
details
xcode 8.3, swift 3.1
full sample
animalsarraytransformtype
import foundation import objectmapper class animalsarraytransformtype: transformtype { public typealias object = [animal] public typealias json = [[string:any]] func transformtojson(_ value: [animal]?) -> [[string : any]]? { if let animals = value { var result = [[string : any]]() animal in animals { result.append(animal.tojson()) } return result } return nil } func transformfromjson(_ value: any?) -> [animal]? { if let animals = value as? [[string: any]] { var resultanimals = [animal]() animal in animals { if let cat = cat(json: animal) { resultanimals.append(cat) } if let fish = fish(json: animal) { resultanimals.append(fish) } } return resultanimals } return nil } }
mapping classes
class foo: mappable, customstringconvertible { required init?(map: map) { } var animals: [animal] = [] func mapping(map: map) { animals <- (map["animals"], animalsarraytransformtype()) } var description: string { var result = "[" (index, animal) in animals.enumerated() { result += "\n[\(index)]:\n\(animal.description)" } result += "\n]\n" return result } } class animal: mappable, customstringconvertible { var type: string? var weight: double? var description: string { var result = "type: \(string(describing: type))\n" result += "weight: \(string(describing: weight))\n" return result } required init?(map: map) { mapping(map: map) } func mapping(map: map) { type <- map["type"] weight <- map["weight"] } } class cat: animal { var catchmice: bool? required init?(map: map) { super.init(map: map) if catchmice == nil { return nil } } override func mapping(map: map) { super.mapping(map: map) catchmice <- map["catchmice"] } override var description: string { var result = super.description result += "catchmice: \(string(describing: catchmice))" return result } } class fish: animal { var swim: bool? required init?(map: map) { super.init(map: map) if swim == nil { return nil } } override func mapping(map: map) { super.mapping(map: map) swim <- map["swim"] } override var description: string { var result = super.description result += "swim: \(string(describing: swim))" return result } }
json file
{ "animals": [ { "type": "cat", "weight": 23, "catchmice": true }, { "type": "fish", "weight": 1, "swim": true } ] }
usage (read json file)
func readjson() { if let path = bundle.main.path(forresource: "json", oftype: "") { { let text = try string(contentsoffile: path, encoding: .utf8) if let dict = try jsonserialization.jsonobject(with: text.data(using: .utf8)!, options: jsonserialization.readingoptions.allowfragments) as? [string: any] { if let foo = foo(json: dict) { print(foo) print(foo.tojson()) } } }catch { print("file read error") } } }
Comments
Post a Comment