Swift 可编码协议字符串编码问题

问题描述

最近我在编码符合 Codable 协议的实体时遇到了一个问题。

这是操场的代码:

class Person: Codable {
    var name: String?
    var age: Int?
    var isDev: Bool?
}

let p1 = Person()
p1.name = "John N."
p1.age = 13
p1.isDev = false

let p2 = Person()
p2.name = "Jack"
p2.age = 19
p2.isDev = true

let people = [p1,p2]
let data = try JSONEncoder().encode(people)
let j = try! JSONSerialization.jsonObject(with: data,options: [])

print(j)

这是我在 Playground 控制台中得到的输出:

enter image description here

如您所见,编码后的 p1 名称有引号,但 p2 没有。所以我的问题是为什么?

附言我注意到的唯一一件事是添加例如设置字符串值时,任何地方的空格符号或下划线都会在 json 中添加引号。 p1.name 包含一个空格,所以它被正确编码。

感谢您的任何想法。

解决方法

j 是反序列化的 JSON 对象,而不是 JSON 字符串(编码数据)。如果您想查看 JSON,请将 data 转换为字符串,因为 that 是 JSON:

print(String(data: data,encoding: .utf8)!)

j 实际上是使用 NSArrayNSDictionary 表示您的 JSON 数据。事实证明,如果您打印包含字符串的 NSDictionarys,引号将被添加到包含空格和/或其他特殊字符的字符串中,以告诉您字符串的实际开始和结束位置。

比较:

print(["name": "hello"] as NSDictionary)
print(["name": "hello world"] as NSDictionary)
print(["hello"] as NSArray)
print(["hello world"] as NSArray)

输出:

{
    name = hello;
}
{
    name = "hello world";
}
(
    hello
)
(
    "hello world"
)
,

这个答案不会解决实际问题,但我认为这是作者想要实现的问题。在发布的代码片段中,您实际上是在打印字典,而不是 JSON 字符串。您正在做以下事情:

  1. Person 对象转换为 JSON 数据
  2. 将 JSON 数据转换为 Dictionary
  3. 打印字典

回想一下,JSON 数据实际上是 JSON 字符串的字节表示。

您只需执行以下操作即可检查 JSON 字符串:

class Person: Codable {
    var name: String?
    var age: Int?
    var isDev: Bool?
}

let p1 = Person()
p1.name = "John N."
p1.age = 13
p1.isDev = false

let p2 = Person()
p2.name = "Jack"
p2.age = 19
p2.isDev = true

let people = [p1,p2]
let data = try JSONEncoder().encode(people)
let jsonString = String(data: data,encoding: .utf8)

print(jsonString ?? "invalid JSON data")

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...