Swift 可编码协议。字符串编码问题
Swift Codable Protocol. String encoding issue
最近我在对符合 Codable 协议的实体进行编码时遇到问题。
这是 Playground 的代码:
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 控制台中得到的输出:
如您所见,编码后的 p1 名称带有引号,但 p2 没有。所以我的问题是为什么?
P.S。我注意到的唯一一件事是添加例如space 符号或下划线在设置字符串值时在任何位置添加引号 json。 p1.name 包含一个 space,因此编码正确。
如有任何想法,我们将不胜感激。
j
是反序列化的 JSON 对象,而不是 JSON 字符串(编码数据)。如果要查看JSON,请将data
转换为字符串,因为那就是JSON:
print(String(data: data, encoding: .utf8)!)
j
实际上是使用 NSArray
和 NSDictionary
表示您的 JSON 数据。事实证明,如果您打印 NSDictionary
s 中的字符串,引号将添加到具有空格 and/or 其他特殊字符的字符串中,以告诉您字符串实际开始和结束的位置。
比较:
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 字符串。您正在做以下事情:
- 将
Person
对象转换为 JSON 数据
- 将 JSON 数据转换为
Dictionary
- 打印字典
回想一下 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")
最近我在对符合 Codable 协议的实体进行编码时遇到问题。
这是 Playground 的代码:
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 控制台中得到的输出:
如您所见,编码后的 p1 名称带有引号,但 p2 没有。所以我的问题是为什么?
P.S。我注意到的唯一一件事是添加例如space 符号或下划线在设置字符串值时在任何位置添加引号 json。 p1.name 包含一个 space,因此编码正确。
如有任何想法,我们将不胜感激。
j
是反序列化的 JSON 对象,而不是 JSON 字符串(编码数据)。如果要查看JSON,请将data
转换为字符串,因为那就是JSON:
print(String(data: data, encoding: .utf8)!)
j
实际上是使用 NSArray
和 NSDictionary
表示您的 JSON 数据。事实证明,如果您打印 NSDictionary
s 中的字符串,引号将添加到具有空格 and/or 其他特殊字符的字符串中,以告诉您字符串实际开始和结束的位置。
比较:
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 字符串。您正在做以下事情:
- 将
Person
对象转换为 JSON 数据 - 将 JSON 数据转换为
Dictionary
- 打印字典
回想一下 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")