Reputation: 3300
I want to send a struct
to another player in GameCenter.
I have read the other questions about this, however, I cannot get any of them to work.
I need to get @"1234"
into a char[4]
(ex char[0] = '1', char[1] = '2', etc)
I have tried [NSString UTF8String]
, but it doesn't seem to do what I want.
It assigns fine, but when I pull it back into NSString *
with [NSString stringWithUTF8String:]
, It returns blank.
If someone could show me the conversion to and from, it would be greatly appreciated.
Thanks.
EDIT:
I can't get it to work :/ Here is my code (the abridged version):
Matchmaker.h
enum { NChars = 4 };
typedef struct {
MessageType messageType;
} Message;
typedef struct {
Message message;
char code[NChars];
} MessageGameCode;
@interface Matchmaker : CCLayer <GameCenterMasterDelegate>{
NSString *_code;
}
@property (nonatomic,retain) NSString *_code;
Matchmaker.m
@synthesize _code;
-(void)viewDidLoad{
self._code = @"1234";
}
- (void)sendCode {
NSLog(@"Sending Code....");
MessageGameCode message;
message.message.messageType = kMessageTypeGameCode;
NSString * const source = self._code;
const char* const sourceAsUTF8 = source.UTF8String;
for (size_t idx = 0; idx < NChars; ++idx) {
message.code[idx] = sourceAsUTF8[idx];
}
NSData *data = [NSData dataWithBytes:&message length:NChars];
[self sendData:data];
}
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID {
Message *message = (Message *) [data bytes];
if (message->messageType == kMessageTypeGameCode) {
MessageGameCode *codeMessage = (MessageGameCode *)[data bytes];
self._code = [[NSString alloc] initWithBytes:codeMessage->code length:NChars encoding:NSUTF8StringEncoding];
[self setGameState:kGameStateWaitingForStart];
NSLog(@"Game Code Recieved");
NSLog(@"Recieved Code: %@",self._code); //This always shows self._code as blank
}
}
Upvotes: 0
Views: 623
Reputation: 104698
Your attempt will fail because the cstring which you pass to + [NSString stringWithUTF8String:]
is not terminated.
Try this:
NSString * result = [[NSString alloc] initWithBytes:bytes
length:4
encoding:NSUTF8StringEncoding];
Edit
A more complete demonstration:
enum { NChars = 4 };
/* requires error checking */
void transmit() {
NSString * const source = @"1234";
char tmp[NChars] = { 0 };
const char* const sourceAsUTF8 = source.UTF8String;
for (size_t idx = 0; idx < NChars; ++idx) {
tmp[idx] = sourceAsUTF8[idx];
}
/* .. */
}
/* requires error checking */
void receive(const char bytes[NChars]) {
NSString * result = [[NSString alloc] initWithBytes:bytes length:NChars encoding:NSUTF8StringEncoding];
/* ... */
}
Upvotes: 7
Reputation: 27900
There are a couple of possible pitfalls here.
One is that with [NSString UTF8String]
"The returned C string is automatically freed just as a returned object would be released; you should copy the C string if it needs to store it outside of the autorelease context in which the C string is created.". So, depending on how long you're expecting the value to stick around you may need to copy it (for example, using strcpy
)
The other issue is that [NSString UTF8String]
and [NSString stringWithUTF8String:]
both expect NULL-terminated C strings, so you need a char[5], not a char[4] to hold @"1234".
Upvotes: 1
Reputation: 86651
One way is
char bytes[4];
NSData* data = [@"1234" dataUsingEncoding: NSUTF8StringEncoding];
if ([data length] <= 4)
{
memcpy(bytes, [data bytes], [data length]);
}
And to go the other way:
NSString* recodedString = [[NSString alloc] initWithBytes: bytes
length: savedLengthFromBefore
encoding: NSUTF8StringEncoding];
Upvotes: 1