本答案中的所有代码均为伪代码片段,您需要自己将算法转换为Objective-C或其他语言。
您的问题引发了许多问题...... 您从以下内容开始:
我有一个NSData对象。 我需要将其字节转换为字符串并发送为JSON。 描述返回十六进制并且不可靠(根据各种SO帖子)。
这似乎意味着您希望将字节作为字符串编码,以便准备在另一端解码它们回到字节。 如果是这种情况,您有许多选择,例如Base-64编码等。 如果您想要简单的东西,您可以将每个字节都编码为其两个字符的十六进制值,伪代码概述:
NSMutableString *encodedString = @"".mutableCopy;
foreach aByte in byteData
[encodedString appendFormat:@"%02x", aByte];
格式
%02x
表示两个十六进制数字,左边补零。这将生成一个字符串,可以发送为JSON并在另一端轻松解码。通过网络传输的字节大小可能是UTF-8编码的两倍,因为UTF-8是JSON推荐的编码方式。
然而,在回答中,您写道:“但我绝对需要原始位。”您的意思是什么?您的接收方会将其获取到的JSON字符串解释为原始字节序列吗?如果是这样,您需要解决多个问题。JSON字符串是JavaScript字符串的子集,并以UCS-2或UTF-16格式存储,即它们是16位值的序列而不是8位值。如果您将每个字节编码为字符串中的字符,则使用16位表示,如果接收器可以访问字节流,则必须跳过每隔一个字节。当然,如果您的接收器逐个字符访问字符串,则每个16位字符可以被截断回8位字节。现在,您可能认为如果采用此方法,则每个8位字节都可以作为字符串的一部分输出为字符,但那行不通。虽然所有值1-255都是有效的Unicode字符代码点,并且JavaScript/JSON允许字符串中有NULs(0值),但并非所有这些值都是可打印的,您不能在字符串中放置双引号
"
而不对其进行转义,转义字符是
\
-所有这些都需要编码到字符串中。您最终会得到类似以下的内容:
NSMutableString *encodedString = @"".mutableCopy;
foreach aByte in byteData
if (isprint(aByte) && aByte != '"' && aByte != '\\')
[encodedString appendFormat:@"%c", aByte];
otherwise
[encodedString appendFormat:@"\\u00%02x", aByte];
这将生成一个字符串,当被JSON解码器解析时,每个字节都会给您一个字符(16位),其中高8位为零。
然而,如果将此字符串传递给JSON编码器,则会对已经编码的Unicode转义序列进行编码...因此,为了避免这种情况,您真的需要自己将此字符串发送到网络中...
感到困惑了吗?变得复杂了吗?那么为什么要将二进制字节数据作为字符串发送?您从未说明您的高级目标是什么,或者是否已知字节数据的任何信息(例如它是否代表某种编码中的字符)
如果这只是一组字节,则为什么不将其作为数字的JSON数组发送-一个字节只是在0-255范围内的数字。要做到这一点,您可以使用以下代码:
NSMutableArray *encodedBytes = [NSMutableArray new];
foreach aByte in byteData
[encodedBytes addObject:@(aByte)]; // add aByte as an NSNumber object
现在将
encodedBytes
传递给
NSJSONSerialisation
,它会将数字的JSON数组发送到网络上,接收器会反转这个过程,将每个字节重新打包到一个字节缓冲区中,你就可以获得你的字节了。这种方法避免了所有有效字符串、编码和转义问题。希望对你有所帮助。
imageData
是NSData对象,数据是否可表示为JSON字符串? - vadian