【KakaJSONマニュアル】05_JSON回転モデル_05_ダイナミックモデル
3216 ワード
前の記事では、サーバが返すフィールドのコンテンツタイプが不確定な場合があります.当時与えられた解決策は をカスタマイズすることである.不確定な内容がモデル化される場合、KakaJSONはより簡単な実装案 を有する.
例を挙げる
kj_modelValue
またはkj_didConvertToModel
の方法を実現し、実際のニーズに応じてJSONの解析ロジック例を挙げる
struct Book: Convertible {
var name: String = ""
var price: Double = 0.0
}
struct Car: Convertible {
var name: String = ""
var price: Double = 0.0
}
struct Pig: Convertible {
var name: String = ""
var height: Double = 0.0
}
struct Dog: Convertible {
var name: String = ""
var weight: Double = 0.0
}
struct Person: Convertible {
var name: String = ""
var pet: Any?
// `NSArray`、`NSMutableArray`
var toys: [Any]?
// `NSDictionary`、`NSMutableDictionary`
var foods: [String: Any]?
func kj_modelType(from jsonValue: Any?, _ property: Property) -> Convertible.Type? {
switch property.name {
case "toys": return Car.self // `toys` `Car`
case "foods": return Book.self // `foods` `Book`
case "pet":
if let pet = jsonValue as? [String: Any], let _ = pet["height"] {
// `pet` `jsonValue` , `height` key, `Pig`
return Pig.self
}
// `jsonValue` `Dog` `pet`
return Dog.self
default: return nil
}
}
}
//
let name = "Jack"
let dog = (name: "Wang", weight: 109.5)
let pig = (name: "Keke", height: 1.55)
let books = [
(name: "Fast C++", price: 666.0),
(name: "Data Structure And Algorithm", price: 1666.0)
]
let cars = [
(name: "Benz", price: 100.5),
(name: "Bently", price: 300.6)
]
// JSON
let json: [String: Any] = [
"name": name,
"pet": ["name": dog.name, "weight": dog.weight],
// "pet": ["name": pig.name, "height": pig.height],
"toys": [
["name": cars[0].name, "price": cars[0].price],
["name": cars[1].name, "price": cars[1].price]
],
"foods": [
"food0": ["name": books[0].name, "price": books[0].price],
"food1": ["name": books[1].name, "price": books[1].price]
]
]
let person = json.kj.model(Person.self)
XCTAssert(person.name == name)
if let pet = person.pet as? Dog {
XCTAssert(pet.name == dog.name)
XCTAssert(pet.weight == dog.weight)
} else if let pet = person.pet as? Pig {
XCTAssert(pet.name == pig.name)
XCTAssert(pet.height == pig.height)
}
let toy0 = person.toys?[0] as? Car
XCTAssert(toy0?.name == cars[0].name)
XCTAssert(toy0?.price == cars[0].price)
let toy1 = person.toys?[1] as? Car
XCTAssert(toy1?.name == cars[1].name)
XCTAssert(toy1?.price == cars[1].price)
let food0 = person.foods?["food0"] as? Book
XCTAssert(food0?.name == books[0].name)
XCTAssert(food0?.price == books[0].price)
let food1 = person.foods?["food1"] as? Book
XCTAssert(food1?.name == books[1].name)
XCTAssert(food1?.price == books[1].price)