在上一篇文章中提到:有時候服務器返回的某個字段的內容類型多是不肯定的html
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)