【发布时间】:2020-03-31 17:09:23
【问题描述】:
我正在尝试在 GameKit 中接收消息。接收消息的部分运行良好,但我不知道如何正确解码数据。
enum MessageType: Int, Codable {
case BestHost, GameBegin, YourTurn, PlayCard, GameOver
}
struct Message: Codable {
let messageType: MessageType
}
struct MessageBestHost: Codable {
let message: Message
let bestHostId: String
let bestHostName: String
}
我使用上述基础设施来发送和接收我的消息。对于发送,我将消息编码如下,然后将其发送给所有玩家:
func encode<T: Encodable>(_ item: T) throws -> Data {
let encoder = JSONEncoder()
return try encoder.encode(item)
}
func sendBestHost(player: GKPlayer) {
let message = MessageBestHost(message: Message(messageType: MessageType.BestHost), bestHostId: player.gamePlayerID, bestHostName: player.alias)
do {
try sendDataToAllPlayers(data: encode(message))
}
catch {
print("Error: \(error.localizedDescription)")
}
}
接收时我使用这种方法解码数据:
func decode<T: Decodable>(from data:Data) throws -> T {
let decoder = JSONDecoder()
let item = try decoder.decode(T.self, from: data)
return item
}
let message: Message
do {
message = try decode (from: data)
print(message)
} catch {
print (error)
}
if message.messageType == MessageType.BestHost {
do {
let messageBestHost: MessageBestHost = try decode(from: data)
print("\(messageBestHost.bestHostName) hosts the game")
} catch {
print(error)
}
现在的问题是。我首先需要将消息解码为类型:消息,以便过滤正确的子类型并为引用消息类型发挥作用。当尝试将数据转换为 message 类型的变量时,解码(显然)失败,因为发送的数据不包含顶层层级中的 messageType。
Error: No value associated with key CodingKeys(stringValue: \"messageType\", intValue: nil)
如果不能先过滤messageType,我将无法区分不同的消息并执行不同的方法。
我想解决方案可能位于我的数据基础架构中,但我想不出任何方法来完成这项工作。有人知道如何解决这个问题吗?
【问题讨论】:
-
会不会根据类型本身有不同类型的Message或MessageBestHost?如果是这样,那么也许这会有所帮助:stackoverflow.com/questions/59270672/… 如果不是,那么我不明白为什么你不能先将其解码为 MessageBestHost,然后再对其进行过滤。
-
mesasageType提到的所有类型的消息。我只是以 MessageBestHost 为例。这就是为什么我不能一直将它解码为 MessageBestHost,因为 messageType 会改变并且不会总是包含相同的数据。我刚刚查看了提供的链接。在那里你使用协议。我无法将您的示例与我的示例联系起来,因为我不使用协议。您认为在这里使用协议是正确的方法吗?谢谢! -
这取决于您需要如何使用 MessageBestHost。如果在数组中,那么它们应该符合相同的协议。
标签: swift codable jsondecoder