前言
客户端开发项目中,不可避免地需要解析网络数据---将服务端下发的JSON数据解析成客户端可阅读友好的Model。Objective-C下使用最多的是JSONModel,它能在OC Runtime基础下很好地完成解析工作。那么在纯Swift代码中,这个功能是如何实现的?下面开始我们的探索~
手动解析 原生:Swift4.0 JSONDecoder JSONDecoder 问题 及 解决方案手动解析
假设一个User类要解析,Json如下:
{
"userId": 1,
"name": "Jack",
"height": 1.7,
}
对应的创建一个User结构体(也可以是类):
struct User {
var userId: Int?
var name: String?
var height: CGFloat?
}
把JSON转成User
在Swift4.0前,我们以手动解析的方式将JSON model化。给User加一个以JSON为参数的初始化方法,代码如下:
struct User {
...
init?(json: [String: Any]) {
guard let userId = json["userId"] as? Int,
let name = json["name"] as? String,
let height = json["height"] as? CGFloat else { return nil }
self.userId = userId
self.name = name
self.height = height
}
}
依次从json中取出model所需的具体类型的数据,填充到具体对应属性中。如果其中一个转换失败或者没有值,初始化会失败返回nil。
如果某个值不需要强校验,直接取值再赋值,把guard let内的语句去掉。例如,若height不用校验,可看如下代码:
struct User {
...
init?(json: [String: Any]) {
guard let userId = json["userId"] as? Int,
let name = json["name"] as? String else { return nil }
self.userId = userId
self.name = name
self.height = json["height"] as? CGFloat
}
}
原生:Swift4.0 JSONDecoder
2017年6月份左右Swift4.0发布,其中一个重大更新就是JSON的加解密。摆脱手工解析字段的繁琐,聊聊几行代码就可将JSON转换成Model。与Objective-C下的JSONModel极为相似。同样解析上述例子中的User,Swift4.0可以这么写:
struct User: Decodable {
var userId: Int?
var name: String?
var height: CGFloat?
}
let decoder = JSONDecoder()
if let data = jsonString.data(using: String.Encoding.utf8) {
let user = try? decoder.decode(User.self, from: data)
}
so easy~ 与手动解析不同点在于:
1.移除了手写init?方法。不需要手动解了
2.User实现Decodable协议,协议的定义如下:
/// A type that can decode itself from an external representation.
public protocol Decodable {
/// Creates a new instance by decoding from the given decoder.
///
/// This initializer throws an error if reading from the decoder fails, or
/// if the data read is corrupted or otherwise invalid.
///
/// - Parameter decoder: The decoder to read data from.
public init(from decoder: Decoder) throws
}








