Q:

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()?

A:

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

A:

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

}];

