Swift Codeable协议
前言
Swift 4.0版本引入了一种新的对象序列化的方式Codeable
,用于代替原先OC语法的NSCode
协议。
在程序执行过程中,我们经常需要通过网络发送数据,保存数据到磁盘,这往往是一个对象序列化的过程;在Swift4.0开始,系统提供一套对象编解码的协议,可以自动或者自定义的实现对象的序列化。
typealias Codable = Decodable & Encodable
自动解码和编码
想要对象可编码,最简单的方式就是用可编码的类型去声明属性;
为了描述简单,结构体和对象都描述为对象
这些可编码的属性包括:Int
String
Double
Date
Data
URL
等
struct Landmark {var name: Stringvar foundingYear: Int
}
接下来,我们只需要让对象实现Codeable
协议,该对象就自动实现了编码和解码。
struct Landmark: Codable {var name: Stringvar foundingYear: Int// Landmark now supports the Codable methods init(from:) and encode(to:), // even though they aren't written as part of its declaration.
}
但是我们平常开发中,属性往往也是自定义对象,在Codeable
协议中,只需要所有的属性都支持编解码,那么该对象也能编解码。
struct Coordinate: Codable {var latitude: Doublevar longitude: Double
}struct Landmark: Codable {// Double, String, and Int all conform to Codable.var name: Stringvar foundingYear: Int// Adding a property of a custom Codable type maintains overall Codable conformance.var location: Coordinate
}
内置的类型,比如Array
Dictionary
,只需要元素实现了Codeable
,那么也支持编解码。
struct Landmark: Codable {var name: Stringvar foundingYear: Intvar location: Coordinate// Landmark is still codable after adding these properties.var vantagePoints: [Coordinate]var metadata: [String: String]var website: URL?
}
手动解码和编码
如果你对象和编码结构不同,你可以自定义编码和解码协议的实现,完成对象的编码和解码。
struct Coordinate {var latitude: Doublevar longitude: Doublevar elevation: Doubleenum CodingKeys: String, CodingKey {case latitudecase longitudecase additionalInfo}enum AdditionalInfoKeys: String, CodingKey {case elevation}
}
解码实现init(from decoder: Decoder)
extension Coordinate: Decodable {init(from decoder: Decoder) throws {let values = try decoder.container(keyedBy: CodingKeys.self)latitude = try values.decode(Double.self, forKey: .latitude)longitude = try values.decode(Double.self, forKey: .longitude)let additionalInfo = try values.nestedContainer(keyedBy: AdditionalInfoKeys.self, forKey: .additionalInfo)elevation = try additionalInfo.decode(Double.self, forKey: .elevation)}
}
编码实现 encode(to encoder: Encoder)
extension Coordinate: Encodable {func encode(to encoder: Encoder) throws {var container = encoder.container(keyedBy: CodingKeys.self)try container.encode(latitude, forKey: .latitude)try container.encode(longitude, forKey: .longitude)var additionalInfo = container.nestedContainer(keyedBy: AdditionalInfoKeys.self, forKey: .additionalInfo)try additionalInfo.encode(elevation, forKey: .elevation)}
}
JSONEncoder & JSONDecoder
Swift提供了系统的JSON数据的编解码方式,可以将实现Codeable
对象和JSON对象相互转化,非常的简单和方便。
struct GroceryProduct: Codable {var name: Stringvar points: Intvar description: String?
}let pear = GroceryProduct(name: "Pear", points: 250, description: "A ripe pear.")let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrintedlet data = try encoder.encode(pear)
print(String(data: data, encoding: .utf8)!)/* Prints:{"name" : "Pear","points" : 250,"description" : "A ripe pear."}
*/
struct GroceryProduct: Codable {var name: Stringvar points: Intvar description: String?
}let json = """
{"name": "Durian","points": 600,"description": "A fruit with a distinctive scent."
}
""".data(using: .utf8)!let decoder = JSONDecoder()
let product = try decoder.decode(GroceryProduct.self, from: json)print(product.name) // Prints "Durian"
PS
我自己写的一个KV存储库SwiftLvDB,也将支持Codeable
对象存储,敬请关注。
参考
https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types
https://developer.apple.com/documentation/foundation/jsonencoder
https://developer.apple.com/documentation/foundation/jsondecoder
Swift Codeable协议相关推荐
- swift 用协议实现代理传值功能
2019独角兽企业重金招聘Python工程师标准>>> swift 用协议实现代理传值功能 原文 http://blog.csdn.net/whzhaochao/article/d ...
- swift_028(Swift 的协议)
//***********swift学习之28--协议--*************************** /* 协议规定了用来实现某一特定功能所必需的方法和属性. 任意能够满足协议要求的类型被 ...
- Swift 面向协议编程 基础篇 (一) 介绍
前言 好久没有写文章了,期末复习周也到了.在复习的同时顺便开了一个专题,面向协议编程,[ 基础篇 ],[ 进阶篇 ],[ 实践篇 ]. 介绍 首先,面向对象(OOP)大家并不陌生,苹果的很多框架都是以 ...
- Swift 面向协议编程的那些事
一直想写一些 Swift 的东西,却不知道从何写起.因为想写的东西太多,然后所有的东西都混杂在一起,导致什么都写不出来.翻了翻以前在组内分享的一些东西,想想把这些内容整理下,写进博客吧.我对计划要写的 ...
- Swift 使用协议加载Xib
import UIKitprotocol NibLoadable {}extension NibLoadable where Self : UIView {static func loadFromNi ...
- 知道swift为什么是面向协议编程么?不知道,还不快来学习!
swift为什么是面向协议编程 面向协议编程 (Protocol Oriented Programming) 是 Apple 在 2015 年 WWDC 上提出的 Swift 的一种编程范式. 面向协 ...
- Swift协议与扩展
转载:http://www.jianshu.com/p/e70bd6645d88 前言 熟悉Objective-C语言的同学们肯定对协议都不陌生,在Swift中苹果将protocol这种语法发扬的更加 ...
- swift开发之--Protocol(协议)
使用object-c语言的同学们肯定对协议都不陌生,但在swift中苹果将protocol这种语法发扬的更加深入和彻底. Swift中的protocol不仅能定义方法还能定义属性,配合extensio ...
- Swift学习: 从Objective-C到Swift
作者:@方秋枋(GitHub) 这篇文章是自己学习Swift的笔记与深化.希望这篇文章能够帮助已经有Objective-C经验的开发者更快地学习Swift.同时也品味到Swift的精妙之处. 结论放在 ...
最新文章
- [LeetCode]*105.Construct Binary Tree from Preorder and Inorder Traversal
- 当用户控件有异动时,网页某部位作出相应变化
- 伟大:看谷歌如何造福人类健康事业
- 拓荒会员电商“无人区”,考拉海购能否拿下“新船票”?
- Form组件,用ajax发送到后台需要的注意事项
- Go的50坑:新Golang开发者要注意的陷阱、技巧和常见错误[1]
- python切片习题与详细讲解
- 我的idea突然没有SVN了是怎么回事
- pytorch---之item()
- python字符串前缀
- 1980-2010的87个国家/地区的一些经济和金融发展指标简单归纳和解释以及如何套动态面板公式计算
- 详细记录基于vue+nodejs+mongodb构建的商城学习(三)基于项目的vue框架梳理
- matlab示波器有毛刺,在使用示波器时如何消除毛刺?
- Leetcode 1146
- 微信开发学习二 -- 微信开发入门(简单demo)
- APIO2007风铃
- vue项目性能优化——断点续传
- pandas案例之消费金额和消费之间的关联与性别和吸烟与否的关系
- 支持向量机是怎么画分类平面的?
- libreoffice安装+libreoffice转换pdf (linux)