【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)
【KakaJSON手册】05_JSON转Model_05_动态模型的更多相关文章
- OSGI(面向Java的动态模型系统)
		基本简介编辑 OSGI服务平台提供在多种网络设备上无需重启的动态改变构造的功能.为了最小化耦合度和促使这些耦合度可管理,OSGi技术提供一种面向服务的架构,它能使这些组件动态地发现对方.OSGi联 O ... 
- OSGI 面向Java的动态模型系统
		OSGI (面向Java的动态模型系统) OSGi(Open Service Gateway Initiative)技术是Java动态化模块化系统的一系列规范.OSGi一方面指维护OSGi规范的OSG ... 
- 【KakaJSON手册】01_JSON转Model_01_基本用法
		在iOS开发中,后台返回的数据大多是JSON格式,对应地会被网络框架层解析成Swift中的Dictionary.Array.由于数据类型的复杂.字段的繁多,直接使用Dictionary.Array会比 ... 
- 【KakaJSON手册】04_JSON转Model_04_值过滤
		在KakaJSON手册的第2篇文章中提过:由于JSON格式能表达的数据类型是比较有限的,所以服务器返回的JSON数据有时无法自动转换成客户端想要的数据类型 比如客户端想要的是Date类型,服务器返回的 ... 
- UML动态模型图简单介绍
		UML动态模型图描述了系统动态行为的各个方面,包括用例图.序列图.协作图.活动图和状态图.下面就每种图做一个简单介绍: 用例图 用例图描述系统外部的执行者与系统提供的用例之间的某种联系.所谓用例是指对 ... 
- [Unity3D][Vuforia][IOS]vuforia在unity3d中添加自己的动态模型,识别自己的图片,添加GUI,播放视频
		使用环境 unity3D 5 pro vuforia 4 ios 8.1(6.1) xcode 6.1(6.2) 1.新建unity3d工程,添加vuforia 4.0的工程包 Hierarchy中 ... 
- 菜鸟学SSH(十八)——Hibernate动态模型+JRebel实现动态创建表
		项目用的是SSH基础框架,当中有一些信息非常相似,但又不尽同样.假设每个建一个实体的话,那样实体会太多.假设分组抽象,然后继承,又不是特别有规律.鉴于这样的情况.就打算让用户自己配置要加入的字段,然后 ... 
- EFcore与动态模型
		在开发商城系统的时候,大家会遇到这样的需求,商城系统里支持多种商品类型,比如衣服,手机,首饰等,每一种产品类型都有自己独有的参数信息,比如衣服有颜色,首饰有材质等,大家可以上淘宝看一下就明白了.现在的 ... 
- EFcore与动态模型(二)
		上篇文章中介绍了如何使用ef进行动态类型的管理,比如我们定义了ShopDbContext并且注册了动态模型信息,下面的代码实现了动态信息的增加: Type modelType = IRuntimeMo ... 
随机推荐
- 零基础ASP.NET Core WebAPI团队协作开发
			零基础ASP.NET Core WebAPI团队协作开发 相信大家对“前后端分离”和“微服务”这两个词应该是耳熟能详了.网上也有很多介绍这方面的文章,写的都很好.我这里提这个是因为接下来我要分享的内容 ... 
- SQL SERVER 活动监视-sys.dm_exec_requests
			sys.dm_exec_requests (Transact-SQL)应用: 针对 SQL Server 内正在执行的每个请求返回一行.sys.dm_exec_connections.sys.dm_e ... 
- [原创]SSH Tunnel for UDP
			SSH Tunnel for UDP UDP port forwarding is a bit more complicated. We will need to convert the packet ... 
- 记录一次pycharm中,引入其他类可用,下面总是有波浪线,而且Ctrl+b 无法查看类函数的源码
			最近在玩python,发现引入其他的函数们总是有波浪线,但是能够使用,crtl+b却无法看到,非常尴尬,然后查看了原因,记录如下: This inspection detects names that ... 
- 网页学习:day1
			初始准备: Write some function Write a titie Write a article Write some button Button function写法: functio ... 
- java多线程总结-同步容器与并发容器的对比与介绍
			1 容器集简单介绍 java.util包下面的容器集主要有两种,一种是Collection接口下面的List和Set,一种是Map, 大致结构如下: Collection List LinkedLis ... 
- 【SpringCloud】Ribbon如何自定义客户端配置和全局配置
			起因 事情的起因是这样的,公司内部要实现基于Zuul网关的灰度路由,在上线时进行灰度测试,故需要配置业务微服务向Eureka注册的metadata元数据,和自定义Ribbon的负载规则达到只访问灰度服 ... 
- 踩坑 Spring Cloud Hystrix 线程池队列配置
			背景: 有一次在生产环境,突然出现了很多笔还款单被挂起,后来排查原因,发现是内部系统调用时出现了Hystrix调用异常.在开发过程中,因为核心线程数设置的比较大,没有出现这种异常.放到了测试环境,偶尔 ... 
- 查询表格——建立动态表格,使用ajax输入查询条件将后台数据查询出来以表格的形式展示出来
			建立动态表格,使用ajax将前台查询条件传给后台,并将查询结果以表格的形式展示出来. 页面的展示效果如下图所示: 第一步:查询条件的部分: 代码如下: <div class="text ... 
- asn1学习笔记
			INTEGER 类型 1.由于这个类型在解码器中没有针对取值范围进行定义.所以在定义的时候要指定取值范围.如: errorcode::=ERRORCODE (1..12345678) ErrorCod ... 
