Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate through NSData bytes

How can I iterate through [NSData bytes] one by one and append them to an NSMutableString or print them using NSLog()?

like image 810
yannis Avatar asked May 06 '12 20:05

yannis


2 Answers

Rather than appending bytes to a mutable string, create a string using the data:

// Be sure to use the right encoding:
NSString *result = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];

If you really want to loop through the bytes:

NSMutableString *result = [NSMutableString string];
const char *bytes = [myData bytes];
for (int i = 0; i < [myData length]; i++)
{
    [result appendFormat:@"%02hhx", (unsigned char)bytes[i]];
}
like image 158
dreamlax Avatar answered Nov 16 '22 00:11

dreamlax


Update! Since iOS 7, there's a new, preferred way to iterate through all of the bytes in an NSData object.

Because an NSData can now be composed of multiple disjoint byte array chunks under the hood, calling [NSData bytes] can sometimes be memory-inefficient, because it needs to flatten all of the underlying chunks into a single byte array for the caller.

To avoid this behavior, it's better to enumerate bytes using the enumerateByteRangesUsingBlock: method of NSData, which will return ranges of the existing underlying chunks, which you can access directly without needing to generate any new array structures. Of course, you'll need to be careful not to go poking around inappropriately in the provided C-style array.

NSMutableString* resultAsHexBytes = [NSMutableString string];

[data enumerateByteRangesUsingBlock:^(const void *bytes,
                                    NSRange byteRange,
                                    BOOL *stop) {

    //To print raw byte values as hex
    for (NSUInteger i = 0; i < byteRange.length; ++i) {
        [resultAsHexBytes appendFormat:@"%02x", ((uint8_t*)bytes)[i]];
    }

}];
like image 20
Jason LeBrun Avatar answered Nov 16 '22 00:11

Jason LeBrun