MonoTouch:通过GameKit发送/接收NSData

时间:2012-04-29 02:10:51

标签: c# ios xamarin.ios nsdata gamekit

我正在尝试在我的MonoTouch游戏中实现配对。我已经成功实现了通过GameKit连接玩家的系统,但我仍然坚持发送和接收数据。

如何将此Objective-c代码转换为c#?我要发送的数据类型是Vector2类,其中包含XY个浮动组件。

NSError *error;
PositionPacket msg;
msg.messageKind = PositionMessage;
msg.x = currentPosition.x;
msg.y = currentPosition.y;
NSData *packet = [NSData dataWithBytes:&msg length:sizeof(PositionPacket)];
[match sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable error:&error];

if (error != nil)
{
    // handle the error
}

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

常用方式,因为OpenTK.Vector2[Serializable]修饰,将结构序列化为Stream(例如MemoryStream然后从中初始化一个新的NSData,例如使用NSData.FromStream。这样做有相当多的开销,但它适用于任何结构。

更好地使用Stream会将您的值写入其中(例如使用StreamWriter)。这消除了序列化开销(反射),并允许您从不同的值构建流(不创建结构)。

MemoryStream ms = new MemoryStream ();
using (StreamWriter sw = new StreamWriter (ms)) {
    sw.Write (v2.X);
    sw.Write (v2.Y);
}
ms.Position = 0;
var data = NSData.FromStream (ms);

更多复杂(但可能更快方式)是使用unsafe代码和NSData.FromBytes接受IntPtr(指针)和数据的大小。如果您的所有数据都已经在结构中,那么这很容易做到。

hacky 方式是将Vector2转换为monotouch.dll中已知的类型,例如PointF。这样您就可以使用NSData.FromObject了。此API适用于NSObjectNSValue支持的最基本的价值类型和一些基本类型,或monotouch.dll内添加的基本类型,例如RectangleFPointF,...

var v2 = new OpenTK.Vector2 ();
var pt = new System.Drawing.PointF (v2.X, v2.Y);
var data = NSData.FromObject (pt);

答案 1 :(得分:0)

好的,所以我想我在很大程度上想出来了。对于任何有兴趣的人,这是我的解决方案。

unsafe
{
    NSError error = new NSError((NSString)"Test", 0);

    System.IntPtr pointer = Marshal.AllocHGlobal(sizeof(PointF));

    PointF packedData = new PointF(position.X, position.Y);

    Marshal.StructureToPtr(packedData, pointer, false);

    NSData packet = NSData.FromBytes(pointer, (uint)sizeof(PointF));

    currentMatch.SendDataToAllPlayers(packet, GKMatchSendDataMode.Unreliable, error.ClassHandle);

    Marshal.FreeHGlobal(pointer);
}

所以我仍然不确定NSError应该是什么,尽管对于我的项目失败的数据包并不重要。这是接收数据包的代码。

PointF packedData = (PointF)Marshal.PtrToStructure(data.Bytes, typeof(PointF));

var recievedData = new Vector2(packedData.X, packedData.Y);