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 枚举大小写应以小写字母开头