简体   繁体   English

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

[英]iOS Development: How can I encapsulate a string in an NSData object?

I'm building a multiplayer game on the iPhone and I need to send string data to the other players in the game. 我正在iPhone上构建多人游戏,我需要将字符串数据发送给游戏中的其他玩家。 To do that, I need to encapsulate my NSString* string data in an NSData object somehow. 为此,我需要以某种方式将NSString *字符串数据封装在NSData对象中。 Here's an example of how my code is structured... 这是我的代码结构的一个示例...

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)];

So my question is, if StringPacket is a struct defined in my header, what type should the stringToSend property be so that I can easily call the dataWithBytes method of NSData to encapsulate the packet data in an NSData object? 所以我的问题是,如果StringPacket是在标头中定义的结构,则stringToSend属性应为哪种类型,以便我可以轻松调用NSDatadataWithBytes方法将数据包数据封装在NSData对象中?

Thanks for your wisdom! 感谢您的智慧!

At first, you should convert your NSString to UTF8 representation via [NSString UTF8String]. 首先,您应该通过[NSString UTF8String]将NSString转换为UTF8表示形式。 After that, i'd recommend to store in packet string length, and after that - the string characters themself. 在那之后,我建议存储在数据包字符串长度中,然后-字符串字符本身。 All that can be done via appending NSData, created from char* via [NSData dataWithBytes:] 所有这些都可以通过附加NSData来完成,该NSData是通过[NSData dataWithBytes:]从char *创建的

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];

To parse packet back, you should do: 要解析数据包,您应该执行以下操作:

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];

There can be some mistakes since i'm writing from memory, but I think you'll get the idea. 自从我从内存中写入数据以来,可能会有一些错误,但是我想您会明白的。

If your strings have a maximum length, it's rather easy and can be done efficiently. 如果您的字符串有最大长度,这很简单并且可以有效地完成。 So, assuming your strings max length for these packets is 255 and you've decided to use UTF-8 to encode your strings (both sides need to agree which encoding they're using), you could do it like this: 因此,假设这些数据包的字符串最大长度为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)];

Now you will have a proper C string in your packet that is at most 255 bytes of string data and the null terminator. 现在,您的数据包中将包含一个适当的C字符串,该字符串最多为255个字节的字符串数据和空终止符。 Note, if your string can't be encoded to UTF8 in the size you gave it, the method will return NO, so your real code should actually check for that and handle it. 请注意,如果无法使用您给定的大小将字符串编码为UTF8,则该方法将返回NO,因此您的实际代码应实际对其进行检查和处理。

If you can't have a size limit, you can basically do the same thing, but you have to deal with dynamically allocating the memory, copying the bytes, creating the data and properly freeing the memory at the right time, so it becomes much more involved but it's the same basic idea. 如果没有大小限制,则基本上可以执行相同的操作,但是必须处理动态分配内存,复制字节,创建数据并在适当的时间正确释放内存,因此它变得非常重要。涉及更多,但这是相同的基本思想。 See also the method -getBytes:maxLength:usedLength:encoding:options:range:remainingRange: on NSString, it can be very useful in generating these messages where the string size is dynamic and totally unknown. 另请参见-getBytes:maxLength:usedLength:encoding:options:range:remainingRange: ,在生成这些消息(字符串大小是动态的且完全未知)时,它非常有用。

For the most simple case, however, the code above should get the job done. 但是,对于最简单的情况,上面的代码应该可以完成工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM