• 【KakaJSON手册】05_JSON转Model_05_动态模型


    上一篇文章中提到:有时候服务器返回的某个字段的内容类型可能是不确定的

    • 当时给出的解决方案是实现kj_modelValue或者kj_didConvertToModel方法,根据实际需求自定义JSON的解析逻辑
    • 如果不确定的内容是要转成模型,KakaJSON有更简单的实现方案

    举例

    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)
    
  • 相关阅读:
    Selenium之编辑框操作
    Selenium之勾选框操作
    Selenium之单选框操作
    [复习资料]组合计数学习笔记
    ARC104游记
    [被踩计划] 题解 [省选联考 2020 A 卷] 作业题
    题解 [SEERC2019]Game on a Tree
    [被踩计划] 题解 [NOI2020]美食家
    [被踩计划] 题解 [省选联考 2020 A 卷] 组合数问题
    [被踩计划] 题解 括号树
  • 原文地址:https://www.cnblogs.com/mjios/p/11367149.html
Copyright © 2020-2023  润新知