📄
Henry
  • Henry的神秘小屋
  • 其他
    • 字节码与机器码的区别?
  • ObjectiveC
    • NSInvocation
    • 检测OC项目中未使用的方法
    • Method Selector
    • 消息转发
  • Swift
    • 检测Swift项目中未使用的类 方法 属性
    • NSCoding
    • Mirror
    • JSONEncode JSONDecode
    • Any AnyObject AnyClass
    • is as? as! as
  • Cocoapods
    • 看懂Podfile.lock文件
    • 在编写的Pod中使用宏预编译
  • iOS
    • 苹果应用 保持画面流畅
    • 关于计算机展示图像的一些问题
    • @testable
    • iOS中URLRequest的缓存策略
    • CodePush接入流程
    • H5在WKWebView中读取沙盒文件
    • FDLog App客户端日志系统
    • 如何实现JSBridge基于WKWebView
    • 网络请求各个指标的度量
    • iOS13 UIModalPresentationStyle
    • 实现H5离线包机制
    • NSURLProtocol 拦截器
    • Framework
    • Lock
    • CFNetwork NSURLSession NSURLConnection
    • setNeedsLayout layoutIfNeeded layoutSubviews
    • StackView
    • Flutter Method Channel:从Dart到Native调用链
    • JSONSerialization.ReadingOptions
    • JSONSerialization.WritingOptions
    • RunLoop高级2
    • RunLoop高级1
    • RunLoop中级
    • RunLoop初级
    • LineBreak AutoShrink
    • 如何给H5出WebView调试包
    • TODO、FIXME、!!!、???、MARK
    • Operation的使用
    • UserDefault
    • 了解WKWebView
    • 输出日志信息到系统控制台
    • Float Double 失去精度问题
    • 使用xcodebuild命令打包导出
    • 在iOS项目中使用C++定义的模块
    • 证书问题
    • 创建常驻线程
  • 源码
    • 阅读PINCache源码
    • 解读AspectHook
    • HandyJSON是如何实现的?
  • 汇编
    • 看懂汇编
由 GitBook 提供支持
在本页
  • JSONEncode JSONDecode 的出现
  • JSON 反序列化成 Model 的规则

这有帮助吗?

  1. Swift

JSONEncode JSONDecode

序列化模型到 JSON,和反序列化 JSON 到模型,在 Swift4 之前一直都比较麻烦,所以像一些第三方库就非常的流行,比如 SwiftJSON,HandyJSON 等,例如我们在 Swift3 下,只能使用 JSONSerialization 这个类,进行序列化和反序列化,但是有一个明显的问题没办法解决。

JSONSerialization 无法将 JSON 直接反序列化成模型,只能反序列成字典,数组,String 这种系统内置类型。 也就是为什么,HandyJson 这种第三方库会非常的流行。

例如:

let json = try? JSONSerialization.jsonObject(with: data, options: []) 
if  let recipe = json as? [String: Any]
{ if  let yield = recipe["yield"] as? Int 
  { recipeObject.yield = yield }
 }

JSONEncode JSONDecode 的出现

在 Swift4 出来之后,系统提供了 Codable 协议 ,JSONEncode,JSONDecode 类型, 解决了反序列化成模型的问题。

下面我们举几个使用例子

1.模型转换成 JSON

例如:

struct User: Codable {
    var name: String
    var age: String
    var gender: String
}

let user = User(name: "Henry", age: "21", gender: "male")
let encoder = JSONEncoder()
let data = try! encoder.encode(user)
let str = String(data: data, encoding: .utf8)
print("str:\(str)")

// `str:Optional("{\"name\":\"Henry\",\"age\":\"21\",\"gender\":\"male\"}")`

2.JSON 转换成模型

例如:

let userJSONStr = """
{"name":"John","age":"14","gender":"male"}
"""

struct User: Codable {
    var name: String
    var age: String
    var gender: String
}

let decoder = JSONDecoder()
let user = try! decoder.decode(User.self, from: userJSONStr.data(using: .utf8)!)
print("[STRUCT] user.name:\(user.name)")


// [STRUCT] user.name:John
// [CLASS] user.name:John

JSON 反序列化成 Model 的规则

我举了两个例子,图解什么样的数据结构可以映射成功。

例子 2: 可以看到,很 cool 使用枚举类型来嵌入我们的模型,但是在验证中得出,只要服务器下发的字段,无法匹配上这个枚举,就会导致反序列化失败,整个 Model 无法被反序列化,所以这个还是慎用,如果是你和服务器是严格约定好的,那么没有任何问题。

通过上图的例子,你可以清楚看到,JSONDecode 是严格按照数据类型来反序列化的,也就是,比如你和服务器订好了,这个字段 A 的类型就是一个 String,但是某一天你改了类型,改成了 Int,那么不好意思,这个反序列化会失败,整个 Model 都不能被解析出来,但是比如服务器去掉了这个字段,我只需要把模型中的类型,换成可选类型,还是可以映射成功的。

上一页Mirror下一页Any AnyObject AnyClass

最后更新于5年前

这有帮助吗?

例子 1:

WechatIMG1127.png

最后 这篇文章只是一个最基础的讲解,反序列化的能与不能没,如果想要具体查看详细的使用,更多用法,可以去这里 。

https://www.raywenderlich.com/3418439-encoding-and-decoding-in-swift
WechatIMG1126.png