Swift Json实例详细解析

2020-01-09 00:10:36丽君

Decodable协议只有一个方法public init(from decoder: Decoder) throws---以Decoder实例进行初始化,初始化失败可能抛出异常。庆幸的是,只要继承Decodable协议,系统会自动检测类中的属性进行初始化工作,省去了人工解析的麻烦~

3.使用了JSONDecoder。它是真正的解析工具,主导整个解析过程

读到这里,是不是觉得人生从黑暗迈向了光明~~

可是,它并不完美...

JSONDecoder问题及方案

解析JSON经常遇到这样两种不一致问题:

服务端下发的key跟端上不一致。比如,服务端下发key="order_id",端上定义key="orderId" 服务端下发的日期表达是yyyy-MM-dd HH:mm或者时间戳,但端上是Date类型 服务端下发的基本类型和端上定义的不一致。服务端下发的是String,端上定义的Int,等

前两个问题JSONDecoder都能很好地解决。

第一个key不一致问题,JSONDecoder有现成的方案。以上面介绍的例子来说,假设服务端返回的key是user_id而不是userId,那么我们可以使用JSONDecoder的CodingKeys像JSONModel一样对属性名称在加解密时的名称做转换。User修改如下:


struct User: Decodable {
 var userId: Int?
 var name: String?
 var height: CGFloat? 
 enum CodingKeys: String, CodingKey {
  case userId = "user_id"
  case name
  case height
 }
}

第二个,Date转换问题。JSONDecoder也为我们提供了单独的API:


open class JSONDecoder {
 /// The strategy to use for decoding `Date` values.
 public enum DateDecodingStrategy {

  /// Defer to `Date` for decoding. This is the default strategy.
  case deferredToDate

  /// Decode the `Date` as a UNIX timestamp from a JSON number.
  case secondsSince1970

  /// Decode the `Date` as UNIX millisecond timestamp from a JSON number.
  case millisecondsSince1970

  /// Decode the `Date` as an ISO-8601-formatted string (in RFC 3339 format).
  case iso8601

  /// Decode the `Date` as a string parsed by the given formatter.
  case formatted(DateFormatter)

  /// Decode the `Date` as a custom value decoded by the given closure.
  case custom((Decoder) throws -> Date)
 }
 ......
 /// The strategy to use in decoding dates. Defaults to `.deferredToDate`.
 open var dateDecodingStrategy: JSONDecoder.DateDecodingStrategy
}

设置好了JSONDecoder属性dateDecodingStrategy后,解析Date类型就会按照指定的策略进行解析。

类型不一致

至此,JSONDecoder为我们提供了

解析不同key值对象 Date类型可自定义转换 Float在一些正负无穷及无值得特殊表示。(出现的概率很少,不作具体说明了)

但遇到基本类型端上与服务端不一致时(比如一个数字1,端上的Code是Int型,服务端下发String:"1"),JSONDecoder会抛出typeMismatch异常而终结整个数据的解析。