我有一个NSData对象。我需要将其字节转换为字符串并作为JSON发送。 description
返回十六进制并且不可靠(根据各种SO海报)。所以我正在查看这样的代码:
NSUInteger len = [imageData length];
Byte *byteData = (Byte*)malloc(len);
[imageData getBytes:&byteData length:len];
然后如何将byteData作为JSON发送?我想发送原始字节。
CODE:
NSString *jsonBase64 = [imageData base64EncodedString];
NSLog(@"BASE 64 FINGERPRINT: %@", jsonBase64);
NSData *b64 = [NSData dataFromBase64String:jsonBase64];
NSLog(@"Equal: %d", [imageData isEqualToData:b64]);
NSLog(@"b64: %@", b64);
NSLog(@"original: %@", imageData);
NSString *decoded = [[NSString alloc] initWithData:b64 encoding:NSUTF8StringEncoding];
NSLog(@"decoded: %@", decoded);
除了最后一行 - decoded
之外,我获得了所有值的值。
哪会告诉我原始字节没有格式化为NSUTF8encoding?
答案 0 :(得分:6)
您是否尝试过使用此类内容:
@implementation NSData (Base64)
- (NSString *)base64EncodedString
{
return [self base64EncodedStringWithWrapWidth:0];
}
这会将你的NSData转换为base64字符串,而另一方面你需要解码它。
编辑:@Lucas说你可以这样做:NSString *myString = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];
但由于一些特殊的字符,我对这个方法有一些问题,因此我开始使用base64字符串进行通信。
EDIT3:尝试此方法base64EncodedString
@implementation NSData (Base64)
- (NSString *)base64EncodedString
{
return [self base64EncodedStringWithWrapWidth:0];
}
//Helper Method
- (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth
{
//ensure wrapWidth is a multiple of 4
wrapWidth = (wrapWidth / 4) * 4;
const char lookup[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
long long inputLength = [self length];
const unsigned char *inputBytes = [self bytes];
long long maxOutputLength = (inputLength / 3 + 1) * 4;
maxOutputLength += wrapWidth? (maxOutputLength / wrapWidth) * 2: 0;
unsigned char *outputBytes = (unsigned char *)malloc((NSUInteger)maxOutputLength);
long long i;
long long outputLength = 0;
for (i = 0; i < inputLength - 2; i += 3)
{
outputBytes[outputLength++] = lookup[(inputBytes[i] & 0xFC) >> 2];
outputBytes[outputLength++] = lookup[((inputBytes[i] & 0x03) << 4) | ((inputBytes[i + 1] & 0xF0) >> 4)];
outputBytes[outputLength++] = lookup[((inputBytes[i + 1] & 0x0F) << 2) | ((inputBytes[i + 2] & 0xC0) >> 6)];
outputBytes[outputLength++] = lookup[inputBytes[i + 2] & 0x3F];
//add line break
if (wrapWidth && (outputLength + 2) % (wrapWidth + 2) == 0)
{
outputBytes[outputLength++] = '\r';
outputBytes[outputLength++] = '\n';
}
}
//handle left-over data
if (i == inputLength - 2)
{
// = terminator
outputBytes[outputLength++] = lookup[(inputBytes[i] & 0xFC) >> 2];
outputBytes[outputLength++] = lookup[((inputBytes[i] & 0x03) << 4) | ((inputBytes[i + 1] & 0xF0) >> 4)];
outputBytes[outputLength++] = lookup[(inputBytes[i + 1] & 0x0F) << 2];
outputBytes[outputLength++] = '=';
}
else if (i == inputLength - 1)
{
// == terminator
outputBytes[outputLength++] = lookup[(inputBytes[i] & 0xFC) >> 2];
outputBytes[outputLength++] = lookup[(inputBytes[i] & 0x03) << 4];
outputBytes[outputLength++] = '=';
outputBytes[outputLength++] = '=';
}
if (outputLength >= 4)
{
//truncate data to match actual output length
outputBytes = realloc(outputBytes, (NSUInteger)outputLength);
return [[NSString alloc] initWithBytesNoCopy:outputBytes
length:(NSUInteger)outputLength
encoding:NSASCIIStringEncoding
freeWhenDone:YES];
}
else if (outputBytes)
{
free(outputBytes);
}
return nil;
}
答案 1 :(得分:6)
在之前的Stack帖子中将字符串视为“不可靠”的原因是因为他们也试图使用NSData对象,其中结尾字节未正确终止 NULL :
NSString *jsonString = [NSString stringWithUTF8String:[nsDataObj bytes]];
// This is unreliable because it may result in NULL string values
以下示例应该为您提供所需的结果,因为NSData字节字符串将正确终止:
NSString *jsonString = [[NSString alloc] initWithBytes:[nsDataObj bytes] length:[nsDataObj length] encoding: NSUTF8StringEncoding];
您走在正确的轨道上,希望这能够帮助您解决当前的问题。祝你好运!
~EDIT~
确保从图像中声明您的NSData对象:
NSData *imageData = [[NSData alloc] init];
imageData = UIImagePNGRepresentation(yourImage);
答案 2 :(得分:3)
从NSData
转换为NSString
时,空终止不是唯一的问题。
NSString
不能保存任意二进制数据。它期望编码。
如果您的NSData
包含无效的UTF-8
序列,initializing the NSString
will fail。
关于这一点,文档并不完全清楚,但对于initWithData
,它说:
如果由于某种原因初始化失败,则返回nil(例如 如果数据不代表编码的有效数据。)
另外:JSON
规范将字符串定义为sequence of Unicode characters。
这意味着即使您能够将原始数据转换为JSON
字符串,如果代码执行UTF-8
验证,解析也可能在接收端失败。
如果您不想使用Base64
,take a look at the answers here。