我正在与之通信的服务器期望以下格式的消息:
identifier
其中data
和struct ActionCableMessage<Message: Encodable>: Encodable {
let command: Command
let identifier: CableChannel
let data: Message?
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(command, forKey: .command)
try container.encode(identifier, forKey: .identifier) // ????
}
private enum CodingKeys: String, CodingKey {
case command, identifier, data
}
}
值是转义的json字符串。
到目前为止,我已经拥有了:
protocol
但是我不知道该怎么办。我认为我需要一个CableChannel
和Message
可以符合的extension
,并提供一个实现了encode (to encoder: Encoder)
的{{1}}功能,以确保Encoder
必须为JSONEncoder
,如果是,则使用该值将其自身的值重写为转义的json字符串。
我还需要将其解码回ActionCableMessage
结构,但是我还没走那么远。
答案 0 :(得分:1)
我认为我需要一个CableChannel和Message可以遵循的协议
好吧,该协议为Encodable
(如果愿意,也可以为Codable
)。
// just implement these as you normally would
extension CableChannel : Encodable { ... }
extension Message : Encodable { ... }
然后在ActionCableMessage
中,使用另一个编码器将内部对象编码为JSON数据,然后将其转换为字符串,然后对该字符串进行编码:
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(command, forKey: .command)
let subencoder = JSONEncoder()
let identifierString = try String(data: subencoder.encode(identifer), encoding: .utf8)
try container.encode(identifierString, forKey: .identifier)
// do the same for "data"
}