codable swift_如何使用Swift Codable与JSON相互转换

本文介绍了如何利用Swift的Codable协议将数据模型与JSON进行相互转换,详细讲解了使用Codable进行JSON解析和序列化的步骤,对于Swift开发者处理JSON接口响应提供了指导。
摘要由CSDN通过智能技术生成

codable swift

For this article, I used Xcode 11.4.1 and Swift 5.2. I assume you’re familiar with the basics of Swift.

对于本文,我使用了Xcode 11.4.1和Swift 5.2。 我认为您熟悉Swift的基础知识。

To make iOS Swift apps be able to communicate with servers, we must convert Swift to JSON. In this article, we’ll be looking at how to convert Swift objects to JSON format and the other way around. To enable converting to and from JSON, we’ll be making use of Codable.

为了使iOS Swift应用程序能够与服务器通信,我们必须将Swift转换为JSON。 在本文中,我们将研究如何将Swift对象转换为JSON格式以及其他方法。 为了实现与JSON的相互转换,我们将使用Codable

Codable is a type that Swift objects can conform to which allows converters to transform the object into another format or from another format to Swift objects. The format can be any desired. Apple already offers JSON converters for Codable types out of the box.

Codable是Swift对象可以遵循的一种类型,它允许转换器将对象转换为另一种格式或从另一种格式转换为Swift对象。 该格式可以是任何所需的格式。 Apple已经提供了针对Codable类型的JSON转换器

In this article, we’ll learn how to convert JSON objects to Swift (and back) by imitating an Apple accessories seller app. We’ll be converting the JSON object that represents the products the merchant sells. We’ll also be converting an order into JSON format.

在本文中,我们将通过模仿Apple配件销售商应用程序来学习如何将JSON对象转换为Swift(并反向转换)。 我们将转换代表商家销售产品的JSON对象。 我们还将把订单转换为JSON格式。

In this tutorial, we’ll make use of Xcode Playgrounds. Playgrounds offers us an easy way of creating and testing our code without the overhead of running an app.

在本教程中,我们将使用Xcode Playgrounds。 Playgrounds为我们提供了一种创建和测试代码的简便方法,而无需运行应用程序。

如何使用Swift Codable将JSON转换为Swift(反之亦然) (How to Convert JSON to Swift (and Vice Versa) Using Swift Codable)

The steps we’ll take:

我们将采取的步骤:

  1. Create a new Playground project

    创建一个新的Playground项目
  2. GET the products JSON response

    获取products JSON响应

  3. Convert the products JSON to Swift using Decodable

    使用Decodableproducts JSON转换为Swift

  4. Create the Order object and convert it to JSON using Encodable

    创建Order对象,并使用Encodable将其转换为JSON

Let’s dive in!

让我们潜入吧!

1.创建一个新的Playground项目 (1. Create a new Playground project)

First let’s open Xcode. From menu select File > New > Playground…

首先让我们打开Xcode。 从菜单中选择文件>新建>操场…

Image for post

When prompted with “Choose a template for your new playground,” select the Blank option under the iOS tab. Then click Next.

当出现“选择新操场的模板”提示时,请选择“ iOS”选项卡下的“空白”选项。 然后单击“下一步”。

Image for post

Name the file codable_json, and then click Create.

将文件命名为codable_json ,然后单击“创建”。

2.获取“产品” JSON响应 (2. GETting the ‘products’ JSON response)

For this article, we’ll copy and paste the JSON response of the merchants GET products API endpoint. We won’t be making any network requests, as that’s out of scope of this article. Rather, we’ll be working directly with the response body that’d be returned by the server.

对于本文,我们将复制并粘贴商家GET products API端点的JSON响应。 我们不会发出任何网络请求,因为这超出了本文的范围。 相反,我们将直接使用服务器将返回的响应主体。

Copy and paste the following into codable_json:

将以下内容复制并粘贴到codable_json

The above code allocates the JSON response string to a constant named productsJson.

上面的代码将JSON响应字符串分配给名为productsJson的常量。

The JSON response contains an array of products. Each product has three properties: product_id, name, and price. product_id is an integer and, name and price are strings.

JSON响应包含一系列产品。 每个产品都有三个属性: product_idnamepriceproduct_id是整数, nameprice是字符串。

3.使用Decodable将产品JSON转换为Swift (3. Convert the products JSON to Swift using Decodable)

Next, let’s convert the products JSON into a Swift object. We’ll first start with creating a Swift representation of a single product from the JSON array of products. The following represents a single product in JSON:

接下来,让我们将产品JSON转换为Swift对象。 我们首先要从产品的JSON数组创建单个产品的Swift表示形式。 以下内容代表JSON中的单个产品:

{
"product_id": 0,
"name": "iPhone 11 Clear Case",
"price": "38.99"
}

Add the following lines to the Playground:

将以下行添加到游乐场:

struct Product {
}

The Product structure will represent a single product in the JSON string.

Product结构将在JSON字符串中表示单个产品。

Next let’s add its properties. Let’s begin with name and price. Don’t worry about product_id just yet — we’ll come back to it. Both name and price are strings. Within the product structure, add the following two lines:

接下来,让我们添加其属性。 让我们从nameprice开始。 暂时不必担心product_id ,我们product_idnameprice都是字符串。 在产品结构中,添加以下两行:

let name: String
let price: String

Now we have a Product JSON representation in Swift. Next let’s convert the JSON representation of the products to Swift. The converter from JSON to Swift provided by Apple is called JSONDecoder. It’s called decoder because, from Swift’s perspective, it decodes JSON. In order for the decoder to decode JSON to its Swift representation, the Product structure must conform to Decodable.

现在我们在Swift中有了Product JSON表示形式。 接下来,让我们将产品的JSON表示形式转换为Swift。 Apple提供的从JSON到Swift的转换器称为JSONDecoder 。 之所以称为解码器,是因为从Swift的角度来看,它可以解码JSON。 为了使解码器将JSON解码为其Swift表示形式, Product结构必须符合Decodable

Next add : Decodable to the Product structure declaration. Our Product struct should look like the following:

接下来添加: DecodableProduct结构声明中。 我们的Product结构应如下所示:

struct Product: 
let name: String
let price: String
}

Now let’s convert JSON to the Product by adding the following line:

现在,通过添加以下行,将JSON转换为Product

let products = try! JSONDecoder().decode([Product].self, from: productsJson.data(using: .utf8)!)

Let’s print the Swift products to our console. Add the following line:

让我们将Swift产品打印到我们的控制台上。 添加以下行:

print(products)

Finally, run the code by clicking on the blue play button besides the print statement.

最后,通过单击打印语句旁边的蓝色播放按钮运行代码。

Image for post
Click on the blue play button
点击蓝色播放按钮

The console should show something like the following:

控制台应显示以下内容:

Image for post

Great! The JSONDecoder has successfully converted the JSON array of products into an array of Swift products. That was easy!

大! JSONDecoder已成功将JSON产品数组转换为Swift产品数组。 那很简单!

Let’s now add the productId property to our Swift Product. Within the Product struct add the following:

现在,将productId属性添加到我们的Swift Product 。 在“ Product结构中添加以下内容:

let productId: Int

Next, click on the play button next to the print statement.

接下来,单击print语句旁边的播放按钮。

Image for post

You should see the same error as in the screenshot above. So what happened? While the name and price properties converted without a problem, productId raises one.

您应该看到与上面的屏幕快照相同的错误。 所以发生了什么事? 虽然nameprice属性转换没有问题,但productId会加一。

The problem here is the property name in Swift is named productId, while the JSON property name is product_id. The decoder is smart enough to match property names that are equal. However, the JSON property naming usually follow snake_case styling (product_id), whereas Swift follows camelCase styling (productId).

这里的问题是Swift中的属性名称为productId ,而JSON属性名称为product_id 。 解码器足够聪明,可以匹配相等的属性名称。 但是,JSON属性命名通常遵循snake_case样式 ( product_id ),而Swift遵循camelCase样式 ( productId )。

To solve the problem we can either:

要解决该问题,我们可以:

  • Match the property name in Swift to the name on the JSON object

    将Swift中的属性名称与JSON对象上的名称匹配
  • Create custom property-name mapping on the Swift object

    在Swift对象上创建自定义属性名称映射

The first one is an easy change: productId becomes product_id in the Swift Product struct. Hit the play button again.

第一个是一个简单的更改: productId在Swift Product结构中成为product_id 。 再次点击播放按钮。

Image for post

However, I prefer to keep camelCase styling to keep the code looking consistent throughout the code base. In that case, we must tell the JSON decoder how to map the properties. Add the following lines within the Product struct:

但是,我更喜欢保持camelCase样式,以使代码在整个代码库中看起来保持一致。 在这种情况下,我们必须告诉JSON解码器如何映射属性。 在Product结构中添加以下行:

enum CodingKeys: String, CodingKey {
case productId = "product_id"
case name = "name"
case price = "price"
}

The above tells the decoder the property name, or the key, in Swift and it’s equivalent in JSON. Unfortunately, we can’t custom map a single property. Thus, we must declare all Swift properties and their equivalent in JSON when opting in for custom-name mapping.

上面的内容告诉解码器Swift中的属性名称或键,在JSON中等效。 不幸的是,我们无法自定义映射单个属性。 因此,在选择自定义名称映射时,必须在JSON中声明所有Swift属性及其等效项。

Hit the play button again, and see it work!

再次点击播放按钮,看它是否起作用!

Image for post

4.创建一个“订单”对象,并使用Encodable将其转换为JSON (4. Create an ‘Order’ object and convert it to JSON using Encodable)

In this final section, we’ll look at how to convert a Swift object to JSON. We’ll be mimicking an Order creation in the Apple accessories seller’s app. The seller POST Order endpoint expects the following to create an order:

在最后一节中,我们将研究如何将Swift对象转换为JSON。 我们将模仿Apple配件销售商的应用程序中的Order创建。 卖方POST Order端点期望以下内容创建订单:

{
products: [ProductQuantity]
}

The ProductQuantity object for the sellers API looks like the following:

卖方API的ProductQuantity对象如下所示:

{
"product_id": 999,
"quantity": 1
}

Here’s an order example where the customer wishes to buy the wireless charging pad (product ID 1):

这是一个订购示例,客户希望购买无线充电板(产品ID 1):

{
"products": [
{
"product_id": 1,
"quantity": 1
}
]
}

Let’s recreate this order in our Swift Playground. First, let create the ProductQuantity Swift representation. Add the following lines:

让我们在Swift Playground中重新创建此顺序。 首先,让我们创建ProductQuantity Swift表示形式。 添加以下行:

struct ProductQuantity {
let productId: Int
let quantity: Int
}

Next, in order to allow Swift to convert, or encode, ProductQuantity into JSON, the struct must conform to Encodable. Change the ProductQuantity declaration to:

接下来,为了允许Swift将ProductQuantity转换或编码为JSON,该结构必须符合Encodable 。 将ProductQuantity声明更改为:

struct 

Before we convert ProductQuantity to JSON, we must make sure the property names (or keys) matches the one the server is expecting.

在将ProductQuantity转换为JSON之前,我们必须确保属性名称(或 s)与服务器期望的名称匹配。

As we saw before when converting the product JSON to Swift, the productId property name doesn’t match the one expected by the server (which is product_id). Once again, we must tell the converter how to map the property names. Add the following within ProductQuantity:

正如我们在将product JSON转换为Swift时所看到的那样, productId属性名称与服务器期望的名称不匹配(即product_id )。 再一次,我们必须告诉转换器如何映射属性名称。 在ProductQuantity添加以下内容:

enum CodingKeys: String, CodingKey {
case productId = "product_id"
case quantity = "quantity"
}

Next, let’s create the structure to represent an Order. Add the following lines at the end of the Playground file:

接下来,让我们创建表示Order的结构。 在Playground文件的末尾添加以下行:

struct Order: Encodable {
let products: [ProductQuantity]
}

Let’s create an order for the wireless charging pad with product ID 1. Add the following line of code:

让我们为产品编号为1的无线充电板创建一个订单。添加以下代码行:

let order = Order(products: [ProductQuantity(productId: 1, quantity: 1)])

Finally, let’s convert our order to JSON and print it to the console. Add the following lines:

最后,让我们将order转换为JSON并将其打印到控制台。 添加以下行:

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let orderJsonData = try! encoder.encode(order)print(String(data: orderJsonData, encoding: .utf8)!)

Above, we’ve created an instance of JSONEncoder and configured its format to JSON in a nice readable format instead of a single line. Then, we’ve encoded our order. The encoder spits out Data. Thus, we must convert it to String in order to print it to the console. Hit play beside the new print statement.

上面,我们创建了一个JSONEncoder实例,并将其格式配置为JSON格式,可读性好,而不是一行。 然后,我们对订单进行了编码。 编码器吐出Data 。 因此,我们必须将其转换为String才能将其打印到控制台。 点击新印刷声明旁边的播放。

The result:

结果:

Image for post
{
"products" : [
{
"product_id" : 1,
"quantity" : 1
}
]
}

We’ve converted the Swift order to JSON, and it’s ready to send to the server!

我们已经将Swift订单转换为JSON,并且可以发送到服务器了!

摘要 (Summary)

In this, we’ve learned:

在此过程中,我们了解到:

最后说明 (Final Notes)

You can find the completed Playground down below:

您可以在下面找到完整的游乐场:

In this article, we covered how to either convert to an object from JSON or how to convert an object to JSON. You can do two-way conversions of an object to and from JSON by conforming to Codable instead of Encodable or Decodable.

在本文中,我们介绍了如何从JSON转换为对象或如何将对象转换为JSON。 您可以通过遵循Codable而不是EncodableDecodable的方式来实现对象与JSON的双向转换。

Furthermore, this article has only covered the basic use cases of Codable. However, things can get more complicated — for example, when mapping a date string to and from a Date object. That’d be an interesting topic to cover in the future.

此外,本文仅介绍了Codable的基本用例。 但是,事情可能会变得更加复杂-例如,在与Date对象之间来回映射日期字符串时。 将来将是一个有趣的话题。

翻译自: https://medium.com/better-programming/how-to-convert-to-and-from-json-using-swift-codable-e78bf353fff5

codable swift

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值