大佬教程收集整理的这篇文章主要介绍了Swift Json实例详细解析,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
{ "userId": 1,"name": "Jack","height": 1.7,}
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 } }
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 } }
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) }
/// 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 }
public init(from decoder: Decoder) throws
---以Decoder实例进行初始化,初始化失败可能抛出异常。庆幸的是,只要继承Decodable协议,系统会自动检测类中的属性进行初始化工作,省去了人工解析的麻烦~
@H_489_0@3.使用了JSONDecoder。它是真正的解析工具,主导整个解析过程
@H_489_0@读到这里,是不是觉得人生从黑暗迈向了光明~~struct User: Decodable { var userId: Int? var name: String? var height: CGFloat? enum CodingKeys: String,CodingKey { case userId = "user_id" case name case height } }
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 }
前端 |
服务端 |
---|---|
String | Int,Float |
Float | String |
Double | String |
Bool | String,Int |
// 入口方法 JSONDecoder decoder(type:Type data:Data) // 内部类,真实用来解析的 _JSONDecoder unBox(value:Any type:TypE) // Model调用init方法 Decodable init(decoder: Decoder) // 自动生成的init方法调用container Decoder container(keyedBy:CodingKeys) // 解析的容器 KeyedDecodingContainer decoderIfPresent(type:TypE) or decode(type:TypE) // 内部类,循环调用unBox _JSONDecoder unBox(value:Any type:TypE) ...循环,直到基本类型
extension KeyedDecodingContainer { ....... /// Decode (Int,String) -> Int if possiable public func decodeIfPresent(_ type: Int.Type,forKey key: K) throws -> Int? { if let value = try? decode(type,forKey: key) { return value } if let value = try? decode(String.self,forKey: key) { return Int(value) } return nil } ....... /// Avoid the failure just when decoding type of Dictionary,Array,SubModel Failed public func decodeIfPresent<T>(_ type: T.Type,forKey key: K) throws -> T? where T : Decodable { return try? decode(type,forKey: key) } }
decodeIfPresent(_ type: Int.Type,forKey key: K)
是以key的信息解析出Int?值。这里覆盖了KeyedDecodingContainer中的该函数的实现,现在已try?的形式以Int类型解析,解析成功则直接返回,失败则以String类型解析出一个stringvalue,如果解析成功,再把String转换成Int?值。decodeIfPresent<T>(_ type: T.Type,forKey key: K)
可以避免这些场景。至此,当类型过程中出现解析的Optional类型出现不匹配时,我们要不是通过转换,要不就是给其赋值nil,避免了系统此时直接throw exception导致退出整个解析过程的尴尬。
@H_489_0@为何不覆盖decode方法?decodeIfPresent可以返回Optional值,decode返回确定类型值。考虑到如果Model内如果定义的类型是No-Optional型,那么可以认为开发者确定该值必须存在,如果不存在Model很可能是错误的,所以直接fail。
@H_489_0@完整扩展代码点我 (本地下载点我)以上是大佬教程为你收集整理的Swift Json实例详细解析全部内容,希望文章能够帮你解决Swift Json实例详细解析所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。