Swift: 解码从 GameKit 发送的消息
Swift: Decode message sent from GameKit
我正在尝试在 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)
}
现在的问题是。我首先需要将消息解码为 type: Message 以便过滤正确的子类型并为引用 messageType 施展魔法。当尝试将数据转换为 message 类型的变量时,解码(显然)失败了,因为发送的数据在最高层级中不包含 messageType。
Error: No value associated with key CodingKeys(stringValue: \"messageType\", intValue: nil)
如果不能先过滤消息类型,我将无法区分不同的消息和执行不同的方法。
我想解决方案可能在我的数据基础架构中,但我想不出任何方法来实现它。有人知道如何解决这个问题吗?
我可能会尝试这样的事情:
import Foundation
enum MessageType: Int, Codable {
case BestHost, GameBegin, YourTurn, PlayCard, GameOver
}
struct Message: Codable {
let messageType: MessageType
let data: Data
}
struct MessageBestHost: Codable {
let bestHostId: String
let bestHostName: String
}
do {
// Serialize:
let messageBestHost = MessageBestHost(bestHostId: "id", bestHostName: "name")
let messageBestHostData = try JSONEncoder().encode(messageBestHost)
let message = Message(messageType: .BestHost, data: messageBestHostData)
let messageData = try JSONEncoder().encode(message)
try sendDataToAllPlayers(data: encode(message))
// Deserialize:
let messageReceived = try JSONDecoder().decode(Message.self, from: messageData)
if messageReceived.messageType == .BestHost {
let messageBestHostReceived = try JSONDecoder().decode(MessageBestHost.self, from: messageReceived.data)
print(messageBestHostReceived.bestHostId)
print(messageBestHostReceived.bestHostName)
}
} catch {
print("Error: \(error.localizedDescription)")
}
此外 swift 枚举大小写应以小写字母开头
我正在尝试在 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)
}
现在的问题是。我首先需要将消息解码为 type: Message 以便过滤正确的子类型并为引用 messageType 施展魔法。当尝试将数据转换为 message 类型的变量时,解码(显然)失败了,因为发送的数据在最高层级中不包含 messageType。
Error: No value associated with key CodingKeys(stringValue: \"messageType\", intValue: nil)
如果不能先过滤消息类型,我将无法区分不同的消息和执行不同的方法。
我想解决方案可能在我的数据基础架构中,但我想不出任何方法来实现它。有人知道如何解决这个问题吗?
我可能会尝试这样的事情:
import Foundation
enum MessageType: Int, Codable {
case BestHost, GameBegin, YourTurn, PlayCard, GameOver
}
struct Message: Codable {
let messageType: MessageType
let data: Data
}
struct MessageBestHost: Codable {
let bestHostId: String
let bestHostName: String
}
do {
// Serialize:
let messageBestHost = MessageBestHost(bestHostId: "id", bestHostName: "name")
let messageBestHostData = try JSONEncoder().encode(messageBestHost)
let message = Message(messageType: .BestHost, data: messageBestHostData)
let messageData = try JSONEncoder().encode(message)
try sendDataToAllPlayers(data: encode(message))
// Deserialize:
let messageReceived = try JSONDecoder().decode(Message.self, from: messageData)
if messageReceived.messageType == .BestHost {
let messageBestHostReceived = try JSONDecoder().decode(MessageBestHost.self, from: messageReceived.data)
print(messageBestHostReceived.bestHostId)
print(messageBestHostReceived.bestHostName)
}
} catch {
print("Error: \(error.localizedDescription)")
}
此外 swift 枚举大小写应以小写字母开头