Search code examples
iphonenotificationsnsdata

Best way to serialize an NSData into a hexadeximal string


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

Solution

  • 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

    #import <Foundation/Foundation.h>
    
    @interface NSData (NSData_Conversion)
    
    #pragma mark - String Conversion
    - (NSString *)hexadecimalString;
    
    @end
    

    NSData+Conversion.m

    #import "NSData+Conversion.h"
    
    @implementation NSData (NSData_Conversion)
    
    #pragma mark - String Conversion
    - (NSString *)hexadecimalString {
        /* Returns hexadecimal string of NSData. Empty string if data is empty.   */
    
        const unsigned char *dataBuffer = (const unsigned char *)[self bytes];
    
        if (!dataBuffer)
            return [NSString string];
    
        NSUInteger          dataLength  = [self length];
        NSMutableString     *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];
    
        for (int i = 0; i < dataLength; ++i)
            [hexString appendString:[NSString stringWithFormat:@"%02lx", (unsigned long)dataBuffer[i]]];
    
        return [NSString stringWithString:hexString];
    }
    
    @end
    

    Usage:

    NSData *someData = ...;
    NSString *someDataHexadecimalString = [someData hexadecimalString];
    

    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.