Game Center - 使用 Swift 发送和接收数据
Posted
技术标签:
【中文标题】Game Center - 使用 Swift 发送和接收数据【英文标题】:Game Center - sending and receiving data with Swift 【发布时间】:2016-11-18 09:24:11 【问题描述】:我正在尝试将以下结构从一个玩家发送到另一个玩家:
struct GamePacket
var action: String
var pointArray: [CGPoint]
我很难找出将GamePacket
转换为Data
并再次转换回来的正确方法。
这是我目前发送数据包的代码:
func send(packet: GamePacket)
//convert GamePacket to Data here
let data = Data.init()
var remotePlayerArray = [GKPlayer]()
if let currentPlayer = self.currentPlayer, let match = self.match, let playerArray = self.match?.players
for player in playerArray
if player != currentPlayer
remotePlayerArray.append(player)
do
try match.send(data, to: remotePlayerArray, dataMode: GKMatchSendDataMode.reliable)
catch
print("connectionError")
以及接收的代码:
func match(_ match: GKMatch, didReceive data: Data, fromRemotePlayer player: GKPlayer)
//convert Data to GamePacket here
从ObjectiveC
编写的一些示例中,我设法使用类似于以下内容的方法将GamePacket
转换为Data
:
let data = NSData(bytes: &packet, length: MemoryLayout<GamePacket>.size) as Data
但是,我不知道如何在接收端将Data
转换回GamePacket
,我也不确定这是正确的方法。
非常感谢任何帮助。谢谢。
【问题讨论】:
【参考方案1】:使用Codable
struct GamePacket: Codable
var action: String
var pointArray: [CGPoint]
然后你就可以轻松转换成Data
了:
func save<T: Encodable>(_ item: T, to url: URL) throws -> Data
let encoder = JSONEncoder()
return try encoder.encode(item)
func load<T: Decodable>(from data:Data) throws -> T
let decoder = JSONDecoder()
let item = try decoder.decode(T.self, from: data)
return item
【讨论】:
一样快,但不那么脏。 :) 我刚遇到同样的问题,很高兴找到您的解决方案@Tyler A.,谢谢!不幸的是,我还剩下两个问题:1. 我不知道如何处理 URL 参数,因为我试图将解码后的数据保存在像var message = load(from: data)
这样的变量中 2. 当按照 1 中的描述进行操作时,我得到了错误Generic parameter 'T' could not be inferred
你能帮忙吗?【参考方案2】:
一个快速而肮脏的解决方案是这样的:
func encodeGamePacket(packet: GamePacket) -> NSData
return NSData(bytes: &gamePacket, length: MemoryLayout<GamePacket>.size)
func decodeGamePacket(data: NSData) -> GamePacket?
var tempBuffer:GamePacket? = nil
data.getBytes(&tempBuffer, length: MemoryLayout<GamePacket>.size)
return tempBuffer
我自己还没有在 swift 下弄乱直接地址,所以我不完全确定这是否是最好的方法。请注意,我使用了可选的返回类型,您可以在代码中进行不同的设计(可能添加一些检查、解包变量并返回它,或者在检查失败时抛出异常)。
或者,您可以设计一个方法,将您的GamePacket
写入String
(例如,为了便于阅读),然后您可以将其转换为NSData
(字符串有一个data
方法)或者您转将GamePacket
转换为符合NSCoding
的类,该类也提供将自身转换为NSData
的方法。
【讨论】:
以上是关于Game Center - 使用 Swift 发送和接收数据的主要内容,如果未能解决你的问题,请参考以下文章