I am looking for a nice-cocoa way to serialize an NSData object into a hexadecimal string. The idea is to serialize the deviceToken used for notification before sending it to my server.
I have the following implementation, but I am thinking there must be some shorter and nicer way to do it.
+ (NSString*) serializeDeviceToken:(NSData*) deviceToken
{
NSMutableString *str = [NSMutableString stringWithCapacity:64];
int length = [deviceToken length];
char *bytes = malloc(sizeof(char) * length);
[deviceToken getBytes:bytes length:length];
for (int i = 0; i < length; i++)
{
[str appendFormat:@"%02.2hhX", bytes[i]];
}
free(bytes);
return str;
}
Swift + Property.
I prefer to have hex representation as property (the same as
bytes
anddescription
properties):Idea is borrowed from this answer
You can always use [yourString uppercaseString] to capitalize letters in data description
This is a category applied to NSData that I wrote. It returns a hexadecimal NSString representing the NSData, where the data can be any length. Returns an empty string if NSData is empty.
NSData+Conversion.h
NSData+Conversion.m
Usage:
This is "probably" better than calling
[someData description]
and then stripping the spaces, <'s, and >'s. Stripping characters just feels too "hacky". Plus you never know if Apple will change the formatting of NSData's-description
in the future.NOTE: I have had people reach out to me about licensing for the code in this answer. I hereby dedicate my copyright in the code I posted in this answer to the public domain.
Change
%08x
to%08X
to get capital characters.I needed to solve this problem and found the answers here very useful, but I worry about performance. Most of these answers involve copying the data in bulk out of NSData so I wrote the following to do the conversion with low overhead:
This pre-allocates space in the string for the entire result and avoids ever copying the NSData contents out by using enumerateByteRangesUsingBlock. Changing the X to an x in the format string will use lowercase hex digits. If you don't want a separator between the bytes you can reduce the statement
down to just
Here is a faster way to do the conversion:
BenchMark (mean time for a 1024 bytes data conversion repeated 100 times):
Dave Gallagher : ~8.070 ms
NSProgrammer : ~0.077 ms
Peter : ~0.031 ms
This One : ~0.017 ms