iOS开发:如何在NSData对象中封装字符串?

时间:2011-01-08 17:04:54

标签: iphone ipad ios nsdata

我正在iPhone上构建一个多人游戏,我需要将游戏中的字符串数据发送给其他玩家。为此,我需要以某种方式将NSString *字符串数据封装在NSData对象中。这是我的代码结构的一个例子......

typedef struct 
{
   PACKETTYPE packetType;
   ??? stringToSend;  //<---not sure how to store this
} StringPacket;    

StringPacket msg;
msg.packetType = STRING_PACKET;
msg.stringToSend = ...  //  <---not sure what to do here
NSData *packet = [NSData dataWithBytes:&msg length:sizeof(StringPacket)];

所以我的问题是,如果StringPacket是我的标题中定义的结构,stringToSend属性应该是什么类型,以便我可以轻松调用{{1}的dataWithBytes方法将数据包封装在NSData对象中?

感谢您的智慧!

2 个答案:

答案 0 :(得分:3)

首先,您应该通过[NSString UTF8String]将NSString转换为UTF8表示形式。 之后,我建议存储数据包字符串长度,之后 - 字符串字符本身。所有这些都可以通过附加NSData来完成,从char *通过[NSData dataWithBytes:]

创建
NSMutableData packet = [[NSMutableData alloc] init];
[packet appendBytes:&msg.packetType, sizeof(msg.packetType)];
char *str = [yourString UTF8String];
int len = strlen(str);
[packet appendBytes:(void*)&len, sizeof(len)];
[packet appendBytes:(void*)str, len];

要解析数据包,你应该这样做:

NSData packet; // your packet
[packet getBytes:(void*)&packet.msg range:NSMakeRange(0, sizeof(packet.msg))];
int len;
[packet getBytes:(void*)&len range:NSMakeRange(sizeof(packet.msg), sizeof(len)];
NSData *strData = [packet subdataWithRange:NSMakeRange(sizeof(packet.msg) + sizeof(len)), packet.length];
NSString *str = [[NSString alloc] initWithData:strData encoding:UTF8Encoding];

因为我是从记忆中写作的,所以会有一些错误,但我认为你会明白这一点。

答案 1 :(得分:2)

如果您的字符串具有最大长度,则相当容易并且可以有效地完成。因此,假设这些数据包的字符串最大长度为255,并且您决定使用UTF-8对字符串进行编码(双方需要同意它们正在使用的编码),您可以这样做:

typedef struct 
{
   PACKETTYPE packetType;
   uint8_t stringToSend[256];  // UTF8 string with max encoded length of 255 bytes
} StringPacket;    

StringPacket msg;
msg.packetType = STRING_PACKET;
[theString getCString:msg.stringToSend maxLength:256 encoding:NSUTF8StringEncoding];
NSData *packet = [NSData dataWithBytes:&msg length:sizeof(StringPacket)];

现在,您的数据包中将有一个适当的C字符串,该字符串最多包含255个字节的字符串数据和空终止符。请注意,如果您的字符串无法按照您提供的大小编码为UTF8,则该方法将返回NO,因此您的实际代码应该实际检查并处理它。

如果你没有大小限制,你基本上可以做同样的事情,但你必须处理动态分配内存,复制字节,创建数据和正确释放内存,所以它变得更加复杂,但它是相同的基本想法。另请参阅NSString上的方法-getBytes:maxLength:usedLength:encoding:options:range:remainingRange:,它对于生成字符串大小是动态且完全未知的消息非常有用。

但是,对于最简单的情况,上面的代码应该完成工作。