uni-app 编码解码
A quick and easy way to convert your JSON
object to Data models
将JSON
对象转换为Data models
快速简便方法
Codable
was introduced in Swift 4
which helps you convert your JSON to your model and model back to a JSON object. Codable
is a typalias of Decodable
and Encodable
protocols. Codable
is similar to Serialization in Java
Swift 4
中引入了Codable
,可帮助您将JSON转换为模型并将模型转换回JSON对象。 Codable
是一个typalias Decodable
和Encodable
协议。 Codable
类似于Java中的序列化
In this tutorial, we will only be covering
Decodable
in-depth在本教程中,我们将仅深入探讨“可
Decodable
Decodable
is used for converting your JSON object to your data model with the help ofJsonDecoder
Decodable
用于在JsonDecoder
的帮助下将JSON对象转换为数据模型
Let’s take a simple example of how to decode a JSON object to your data-model
让我们举一个简单的示例,说明如何将JSON对象解码为数据模型
- Create your data model and conform to Decodable 创建您的数据模型并符合Decodable
Create an instance of
JsonDecoder
and usedecode(type: T.Type, data: Data)
to decode the theJSON
object toPhotoFeed
.创建一个
JsonDecoder
实例,并使用decode(type: T.Type, data: Data)
JsonDecoder
decode(type: T.Type, data: Data)
将JSON
对象解码为PhotoFeed
。
The type
passed to decode method should conform to Deocodable.
传递给解码方法的type
应符合Deocodable.
Hurray! And just by writing a few lines of code, you have your data-model ready that is mapped from the JSON object. HereJsonDecoder
does the heavy lifting 🏋️♂️for you by mapping each key from the JSON and setting the values of the variables. The manual chores of getting the key from the JSON dictionary and then setting values in model days are far gone. All thanks to Codable
万岁 ! 只需编写几行代码,您就可以准备从JSON对象映射的数据模型。 在这里, JsonDecoder
通过映射JSON中的每个键并设置变量的值来为您完成繁重的任务。 从JSON字典中获取密钥然后在模型日中设置值的手动工作已经远远没有了。 多亏了Codable
《可降解物质》还能做什么? (What else can Decodable do?)
可解码的可选键 (Optional keys in Decodable)
You can mark the variables as optional
for which the JSON object does not contain the value. In below example, the JSON response does not send the postKey
. JsonDecoder ensures that when the variable is marked as optional, it checks the value for the key in a JSON object and then set its value if present.
您可以将变量标记为optional
,而JSON对象不包含该变量的值。 在下面的示例中,JSON响应不发送postKey
。 JsonDecoder确保将变量标记为可选时,它检查JSON对象中密钥的值,然后设置其值(如果存在)。
// MARK: - PhotoFeed
struct PhotoFeed: Decodable {
let id, photoTnURL, photoURL, photoURLScaled: String
let curated: Bool
let postKey: String?
}
编码键 (CodingKey)
CodingKey
tells the JSONDecoder
to map the keys present in the container with the assigned variables. The above API response has id
and photoTnURL
, which does not tell what exactly the variable represents. This can be fixed with CodingKey
. So we rename the keys id
→feedId
and photoTnURL
→ thumbnailUrlString
CodingKey
告诉JSONDecoder
将容器中存在的键与分配的变量进行映射。 上面的API响应具有id
和photoTnURL
,它们不能确切说明该变量代表什么。 可以使用CodingKey
修复此CodingKey
。 因此,我们重命名键id
→ feedId
和photoTnURL
→ thumbnailUrlString
// MARK: - PhotoFeed
struct PhotoFeed: Decodable { let feedId: String // Renamed from id
let thumbnailUrlString: String // Renamed from photoTnURL
let curated: Bool
let photoURL, photoURLScaled: String
let postKey: String
enum CodingKeys: String, CodingKey {
case feedId = "id"
case thumbnailUrlString = "photoTnURL"
case curated, photoURL, photoURLScaled, postKey
}
}
处理嵌套数据 (Handle Nested Data)
Let’s say the API response starts sending you the location
along with the feed. You can add the location in your data-model which will conform to Decodable
. You can add the new Location struct in your PhotoFeed
or as a new struct
outside the PhotoFeed.
假设API响应开始向您发送location
以及Feed。 您可以在数据模型中添加符合Decodable
。 您可以在添加新的定位结构PhotoFeed
或作为一个新的struct
的PhotoFeed之外。
// MARK: - PhotoFeed
struct PhotoFeed: Decodable {
let feedId: String
let thumbnailUrlString: String
let curated: Bool
let photoURL, photoURLScaled: String
let postKey: String
let location: Location
struct Location: Decodable {
var latitude: Double
var longitude: Double
enum CodingKeys: String, CodingKey {
case latitude = "lat"
case longitude = "long"
}
}
enum CodingKeys: String, CodingKey {
case feedId = "id"
case thumbnailUrlString = "photoTnURL"
case curated, photoURL, photoURLScaled, postKey, location
}
}
展平JSON嵌套属性 (Flatten out JSON nested properties)
JSONDecoder
will help you iterate through all the container values. Use decoder.container(keyedBy:) on the decoder to get all the values present in the CodingKey. Similarly nestedContainer(keyedBy: forKey:) will allow you to iterate through the nested container. Using these methods you can iterate over all the keys in the decoder. Let's see this through an example to flatten out the structure
JSONDecoder
将帮助您遍历所有容器值。 使用解码器上的decoder.container(keyedBy :)获取CodingKey中存在的所有值。 同样, nestedContainer(keyedBy:forKey :)将允许您迭代嵌套容器。 使用这些方法,您可以遍历解码器中的所有键。 让我们通过一个示例来弄平结构
// MARK: - PhotoFeed
struct PhotoFeed: Decodable {
let feedId: String
let thumbnailUrlString: String
let curated: Bool
let photoURL, photoURLScaled: String
let postKey: String let latitude: Double
let longitude: Double
enum CodingKeys: String, CodingKey {
case location
case feedId = "id"
case thumbnailUrlString = "photoTnURL"
case curated, photoURL, photoURLScaled, postKey
}
enum LocationKeys: String, CodingKey {
case latitude = "lat"
case longitude = "long"
}// MARK: - init with decoder
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)let location = try values.nestedContainer(keyedBy: LocationKeys.self, forKey: .location)
latitude = try location.decode(Double.self, forKey: .latitude)
longitude = try location.decode(Double.self, forKey: .longitude)feedId = try values.decode(String.self, forKey: .feedId)
thumbnailUrlString = try values.decode(String.self, forKey: .thumbnailUrlString)
curated = try values.decode(Bool.self, forKey: .curated)
photoURL = try values.decode(String.self, forKey: .photoURL)
photoURLScaled = try values.decode(String.self, forKey: .photoURLScaled)
postKey = try values.decode(String.self, forKey: .postKey)
}
}
解码策略 (Decoding strategies)
KeyDecodingStrategy: (KeyDecodingStrategy:)
Sometimes the JSON response not always follows the camelCase
naming convention. There is a good chance that you may have a response that follows snake_case.
有时,JSON响应并不总是遵循camelCase
命名约定。 您很有可能在snake_case.
响应snake_case.
We can set the decoding strategy
that determines how coding keys are decoded from JSON. Let’s take an example to solve this:
我们可以设置decoding strategy
,该decoding strategy
确定如何从JSON解码编码密钥。 让我们举个例子来解决这个问题:
1.useDefaultKeys
: It’s the default strategy. JsonDecoder
will use the same variable names for decoding
1. useDefaultKeys
:这是默认策略。 JsonDecoder
将使用相同的变量名称进行解码
2.convertFromSnake
: It will convert the JSON keys from snake-case🐍
to camel-case🐫
keys present in your data-model
2. convertFromSnake
:它将JSON密钥从snake-case🐍
转换为数据模型中存在的camel-case🐫
密钥
// MARK: - PhotoFeed
struct PhotoFeed: Decodable {
let feedId: String
let photoTnUrl: String
let curated: Bool
let photoUrl, photoUrlScaled: String
let postKey: String
}let data = json.data(using: .utf8)!
let jsonDecoder = JSONDecoder()jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase
let photoFeed = try! jsonDecoder.decode(PhotoFeed.self, from: data)
3.custom
: You can have your custom implementation which returns the correspondingCodingKey
present in your data-model. The below data-model has keys which have youtube
prefixed before every key present in JSON. Using custom decoding strategy, we can remove the prefixed stringyoutube
from every JSON object key so it maps to the variable in PhotoFeed.
3. custom
:您可以使用您的自定义实现,该实现返回数据模型中存在的相应CodingKey
。 以下数据模型的键在JSON中每个键之前都有youtube
前缀。 使用自定义解码策略,我们可以从每个JSON对象键中删除前缀字符串youtube
,以便将其映射到PhotoFeed.
的变量PhotoFeed.
解码日期 (Decoding Dates)
JsonDecoder
supports decoding dates from the JSON response. Here is a list of supported date decoding strategies.
JsonDecoder
支持从JSON响应中解码日期。 这是受支持的日期解码策略的列表。
1.deferredToDate
: Number of seconds elapsed since 1st Jan 2001
represented in double
. A very rare chance you would be using this.
1. deferredToDate
:自1st Jan 2001
年1st Jan 2001
以来经过的秒数,以double
表示。 您将很少使用此功能。
2. iso8601
: This is the most widely used date-format. Use this link to understand more about date-format used under iso8601
2. iso8601
:这是使用最广泛的日期格式。 使用此链接可了解有关iso8601
下使用的日期格式的更多信息。
3. formatted(DateFormatter)
: You can add a custom DateFormatter
with required dateFormat
3. formatted(DateFormatter)
:您可以添加具有所需dateFormat的自定义DateFormatter
4.custom((Decoder) -> Date)
: You can write custom code for parsing your date. Let’s say you have a bad JSON containing two date formats, here is a quick way to resolve it using .custom
decoding strategy
4. custom((Decoder) -> Date)
:您可以编写用于解析日期的自定义代码。 假设您有一个错误的JSON,其中包含两种日期格式,这是使用.custom
解码策略解决此问题的快速方法
5.millisecondsSince1970
: It decodes date in milliseconds since midnight UTC on January 1st, 1970
5. millisecondsSince1970
:解码自1970年1月1日午夜UTC以来的日期(以毫秒为单位)
6.secondsSince1970
: Decodes date in seconds since midnight UTC on January 1st, 1970
6. secondsSince1970
:自1970年1月1日午夜UTC以来以秒为单位解码日期
解码原始数据 (Decoding Raw Data)
JsonDecoder
supports strategies for decoding your raw data. Here is a list of supported data decoding strategies
JsonDecoder
支持用于解码原始数据的策略。 以下是受支持的数据解码策略的列表
1.base64
: decodes data using Base 64 decoding
1. base64
:使用Base 64解码对数据进行解码
2.custom((Decoder) -> Data)
: decodes data using a custom function implemented by you.
2. custom((Decoder) -> Data)
:使用由您实现的自定义函数对数据进行解码。
By now you already got a gist of how the default custom decoding works and how would you use them. Still find it difficult to understand, comment below and I will add gist for you
到目前为止,您已经了解了默认自定义解码的工作原理以及如何使用它们。 仍然很难理解,请在下面评论,我将为您添加要点
解码特殊号码 (Decoding Exceptional Numbers)
This strategy is used by a JsonDecoder
when it encounters exceptional floating-point values. In your lifetime you must have encountered when your server returns an invalid “NaN”
. Similarly how to handle +ve infinity and -ve infinity values (which you might have never encountered), if not handled this would just CRASH 💥 your app.
当遇到异常的浮点值时, JsonDecoder
将使用此策略。 在您的一生中,您必须遇到服务器返回无效的“NaN”
。 类似地,如何处理+ ve infinity和-ve infinity值(您可能从未遇到过),如果不处理,则将CRASH app您的应用程序。
Here is how you handle nan
, +veInfinity
and -veInfinity
这是处理nan
, +veInfinity
和-veInfinity
That’s pretty much you what you get in Decodable
🙌
那就是你在《可Decodable
东西》中得到的what
Did I miss a use-case? Let me know in the comments below!
我错过了用例吗? 在下面的评论中让我知道!
翻译自: https://medium.com/flawless-app-stories/complete-guide-to-codable-decodable-b1ff696da24f
uni-app 编码解码