Swift 在 JSON 中没有完整键的情况下将结构编码为数据
Swift encode structs to data without having the full keys in the JSON
出于协议原因,我必须将我的对象转换为 Data
。我在网上找到的所有方法都使用JSON,但由于它是Swift-to-Swift,我想知道是否有为此提供的内置机制。
为什么我不喜欢 JSON?它包括完整的密钥名称,在规模上会产生不必要的开销。让我证明我的意思:
struct Address: Codable {
var city = ""
var street = ""
}
struct Person: Codable {
var name = ""
var adresses = [Address]()
}
let addresses = [Address(city: "NY", street: "123"), Address(city: "LV", street: "456")]
let personA = Person(name: "A", adresses: addresses)
print(personA)
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(personA) {
print(encoded)
let str = String(data: encoded, encoding: .utf8)
print(str) //{\"name\":\"A\",\"adresses\":[{\"street\":\"123\",\"city\":\"NY\"},{\"street\":\"456\",\"city\":\"LV\"}]}
//it includes the complete key nnames in the JSON
}
Swift 是否提供了一种更有效的方式来处理传输的大小?我知道 Protocol Buffers 但这似乎有点矫枉过正
由于您使用的是结构类型,我认为您最好的选择是 Codable。获得更小占用空间的一种方法是通过无键编码应用自定义编码(以及解码)
因此将此添加到 Address
extension Address {
func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(city)
try container.encode(street)
}
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
city = try container.decode(String.self)
street = try container.decode(String.self)
}
}
Person
类似
extension Person {
func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(name)
try container.encode(adresses)
}
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
name = try container.decode(String.self)
adresses = try container.decode([Address].self)
}
}
编码您的示例将得到
33 bytes <-- Down from 83 in my test
["A",[["NY","123"],["LV","456"]]]
出于协议原因,我必须将我的对象转换为 Data
。我在网上找到的所有方法都使用JSON,但由于它是Swift-to-Swift,我想知道是否有为此提供的内置机制。
为什么我不喜欢 JSON?它包括完整的密钥名称,在规模上会产生不必要的开销。让我证明我的意思:
struct Address: Codable {
var city = ""
var street = ""
}
struct Person: Codable {
var name = ""
var adresses = [Address]()
}
let addresses = [Address(city: "NY", street: "123"), Address(city: "LV", street: "456")]
let personA = Person(name: "A", adresses: addresses)
print(personA)
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(personA) {
print(encoded)
let str = String(data: encoded, encoding: .utf8)
print(str) //{\"name\":\"A\",\"adresses\":[{\"street\":\"123\",\"city\":\"NY\"},{\"street\":\"456\",\"city\":\"LV\"}]}
//it includes the complete key nnames in the JSON
}
Swift 是否提供了一种更有效的方式来处理传输的大小?我知道 Protocol Buffers 但这似乎有点矫枉过正
由于您使用的是结构类型,我认为您最好的选择是 Codable。获得更小占用空间的一种方法是通过无键编码应用自定义编码(以及解码)
因此将此添加到 Address
extension Address {
func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(city)
try container.encode(street)
}
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
city = try container.decode(String.self)
street = try container.decode(String.self)
}
}
Person
extension Person {
func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(name)
try container.encode(adresses)
}
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
name = try container.decode(String.self)
adresses = try container.decode([Address].self)
}
}
编码您的示例将得到
33 bytes <-- Down from 83 in my test
["A",[["NY","123"],["LV","456"]]]