具有多种结构的 JSONEncoder
JSONEncoder with multiple structures
嗨,我有多个 JSON 数据包,就像我在下面写的那样。
{
"data" : {
"lng" : 36.159999999999997,
"lat" : 50.359999999999999,
"accuracy" : 5
},
"header" : {
"type" : "loc"
}
}
还有这个
{
"data" : {
"time" : 15646565455,
"tz" : "+2",
"system" : 5
},
"header" : {
"type" : "syn"
}
}
我有我的数据包结构,它适用于一种数据包结构。但是如何将它用于多个数据包结构。
struct Packet : Codable {
enum StructureType : String, Codable {
case location = "loc"
case synchronize = "syn"
}
enum Status: String, Codable {
case OK = "OK"
case NOT = "NOT"
}
struct Header: Codable {
let type: StructureType
let status: Status?
}
var header: Header
struct Data : Codable {
struct LocationStruct : Codable {
var lng: Double
var lat: Double
var accuracy: Double
}
struct SynchronizationStruct: Codable {
var time: Int
var tz: String
var locale: String
}
}
var data: Data
}
现在我想编码 JSON 取决于我的数据
let dataHeader = Packet.Header.init(type: .location, action: nil, ID: nil, dataID: nil, status: nil)
let dataData = Packet.Data.LocationStruct.init(lng: lng, lat: lat, accuracy: acc)
let dataObject = Packet.init(header: dataHeader, data: dataData)
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try! encoder.encode(dataObject)
如何做到这一点,或者我需要为每个数据包使用我的数据结构的其他结构?
我建议你创建 3 个结构。
- 主要有数据结构和头结构。
每个结构都必须符合 Codable
协议。
struct Structure: Codable {
let data: Data
let header: Header
init(data: Data, header: Header) {
self.data = data
self.header = header
}
enum CodingKeys: String, CodingKey { case data, header }
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(data, forKey: .data)
try container.encodeIfPresent(header, forKey: .header)
}
}
struct Data: Codable {
let lng: Double?
let lat: Double?
let accuracy: Double?
let time: Int?
let tz: String?
let system: Int?
}
struct Header: Codable {
let type: String
}
let firstStructure = Structure(data: Data(lng: 36.159999999999997, lat: 50.359999999999999, accuracy: 5, time: nil, tz: nil, system: nil), header: Header(type: "loc"))
let secondStructure = Structure(data: Data(lng: nil, lat: nil, accuracy: nil, time: 15646565455, tz: "+2", system: 5), header: Header(type: "syn"))
let encoder = JSONEncoder()
let firstData = try? encoder.encode(firstStructure)
let secondData = try? encoder.encode(secondStructure)
print(String(data: firstData!, encoding: String.Encoding.ascii))
print(String(data: secondData!, encoding: String.Encoding.ascii))
如有任何问题,请随时填写。下次在您提出任何问题之前,请尝试 google 它。有很多解决此类问题的好教程。
我有两个主要模型对象的结构,Location
和 Synchronization
。然后我将它们定义为符合某些协议,我们在协议中指定我们如何知道哪个 "header" 适用于哪种类型的有效负载。然后我会制作一个通用数据包,可以打包这两种可能的有效载荷:
enum PayloadType: String, Codable {
case location = "loc"
case synchronize = "syn"
}
protocol Payload: Codable {
var payloadType: PayloadType { get }
}
struct Location: Payload {
let lat: Double
let long: Double
let accuracy: Double
let payloadType = PayloadType.location
enum CodingKeys: String, CodingKey {
case lat,long,accuracy
}
}
struct Synchronization: Payload {
let time: Int
let tz: String
let system: Int
let payloadType = PayloadType.synchronize
enum CodingKeys: String, CodingKey {
case time, tz, system
}
}
struct Packet<T: Payload>: Codable {
let data: T
let header: PayloadType
init(payload: T) {
data = payload
header = payload.payloadType
}
}
那么你可以这样做:
let location = Location(lat: 36.16, long: 50.36, accuracy: 5)
let packet = Packet(payload: location)
let json = try! encoder.encode(packet)
导致:
{
"data" : {
"lat" : 36.159999999999997,
"long" : 50.359999999999999,
"accuracy" : 5
},
"header" : "loc"
}
或
let location = Synchronization(time: 15646565455, tz: "+2", system: 5)
let packet = Packet(payload: location)
let json = try! encoder.encode(packet)
导致:
{
"data" : {
"system" : 5,
"time" : 15646565455,
"tz" : "+2"
},
"header" : "syn"
}
嗨,我有多个 JSON 数据包,就像我在下面写的那样。
{
"data" : {
"lng" : 36.159999999999997,
"lat" : 50.359999999999999,
"accuracy" : 5
},
"header" : {
"type" : "loc"
}
}
还有这个
{
"data" : {
"time" : 15646565455,
"tz" : "+2",
"system" : 5
},
"header" : {
"type" : "syn"
}
}
我有我的数据包结构,它适用于一种数据包结构。但是如何将它用于多个数据包结构。
struct Packet : Codable {
enum StructureType : String, Codable {
case location = "loc"
case synchronize = "syn"
}
enum Status: String, Codable {
case OK = "OK"
case NOT = "NOT"
}
struct Header: Codable {
let type: StructureType
let status: Status?
}
var header: Header
struct Data : Codable {
struct LocationStruct : Codable {
var lng: Double
var lat: Double
var accuracy: Double
}
struct SynchronizationStruct: Codable {
var time: Int
var tz: String
var locale: String
}
}
var data: Data
}
现在我想编码 JSON 取决于我的数据
let dataHeader = Packet.Header.init(type: .location, action: nil, ID: nil, dataID: nil, status: nil)
let dataData = Packet.Data.LocationStruct.init(lng: lng, lat: lat, accuracy: acc)
let dataObject = Packet.init(header: dataHeader, data: dataData)
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try! encoder.encode(dataObject)
如何做到这一点,或者我需要为每个数据包使用我的数据结构的其他结构?
我建议你创建 3 个结构。
- 主要有数据结构和头结构。
每个结构都必须符合 Codable
协议。
struct Structure: Codable {
let data: Data
let header: Header
init(data: Data, header: Header) {
self.data = data
self.header = header
}
enum CodingKeys: String, CodingKey { case data, header }
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(data, forKey: .data)
try container.encodeIfPresent(header, forKey: .header)
}
}
struct Data: Codable {
let lng: Double?
let lat: Double?
let accuracy: Double?
let time: Int?
let tz: String?
let system: Int?
}
struct Header: Codable {
let type: String
}
let firstStructure = Structure(data: Data(lng: 36.159999999999997, lat: 50.359999999999999, accuracy: 5, time: nil, tz: nil, system: nil), header: Header(type: "loc"))
let secondStructure = Structure(data: Data(lng: nil, lat: nil, accuracy: nil, time: 15646565455, tz: "+2", system: 5), header: Header(type: "syn"))
let encoder = JSONEncoder()
let firstData = try? encoder.encode(firstStructure)
let secondData = try? encoder.encode(secondStructure)
print(String(data: firstData!, encoding: String.Encoding.ascii))
print(String(data: secondData!, encoding: String.Encoding.ascii))
如有任何问题,请随时填写。下次在您提出任何问题之前,请尝试 google 它。有很多解决此类问题的好教程。
我有两个主要模型对象的结构,Location
和 Synchronization
。然后我将它们定义为符合某些协议,我们在协议中指定我们如何知道哪个 "header" 适用于哪种类型的有效负载。然后我会制作一个通用数据包,可以打包这两种可能的有效载荷:
enum PayloadType: String, Codable {
case location = "loc"
case synchronize = "syn"
}
protocol Payload: Codable {
var payloadType: PayloadType { get }
}
struct Location: Payload {
let lat: Double
let long: Double
let accuracy: Double
let payloadType = PayloadType.location
enum CodingKeys: String, CodingKey {
case lat,long,accuracy
}
}
struct Synchronization: Payload {
let time: Int
let tz: String
let system: Int
let payloadType = PayloadType.synchronize
enum CodingKeys: String, CodingKey {
case time, tz, system
}
}
struct Packet<T: Payload>: Codable {
let data: T
let header: PayloadType
init(payload: T) {
data = payload
header = payload.payloadType
}
}
那么你可以这样做:
let location = Location(lat: 36.16, long: 50.36, accuracy: 5)
let packet = Packet(payload: location)
let json = try! encoder.encode(packet)
导致:
{
"data" : {
"lat" : 36.159999999999997,
"long" : 50.359999999999999,
"accuracy" : 5
},
"header" : "loc"
}
或
let location = Synchronization(time: 15646565455, tz: "+2", system: 5)
let packet = Packet(payload: location)
let json = try! encoder.encode(packet)
导致:
{
"data" : {
"system" : 5,
"time" : 15646565455,
"tz" : "+2"
},
"header" : "syn"
}