Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 将NSData字节数组转换为字符串?_Objective C_Json_Cocoa_Nsdata - Fatal编程技术网

Objective c 将NSData字节数组转换为字符串?

Objective c 将NSData字节数组转换为字符串?,objective-c,json,cocoa,nsdata,Objective C,Json,Cocoa,Nsdata,我有一个NSData对象。我需要将其字节转换为字符串并作为JSON发送说明返回十六进制且不可靠(根据各种SO海报)。所以我在看这样的代码: NSUInteger len = [imageData length]; Byte *byteData = (Byte*)malloc(len); [imageData getBytes:&byteData length:len]; @implementation NSData (Base64) - (NSString *)base64Encode

我有一个NSData对象。我需要将其字节转换为字符串并作为JSON发送<代码>说明返回十六进制且不可靠(根据各种SO海报)。所以我在看这样的代码:

NSUInteger len = [imageData length];
Byte *byteData = (Byte*)malloc(len);
[imageData getBytes:&byteData length:len];
@implementation NSData (Base64)
- (NSString *)base64EncodedString
{
    return [self base64EncodedStringWithWrapWidth:0];
}
NSString *myString = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];
然后如何将byteData作为JSON发送?我想发送原始字节

代码:

除了最后一行-
解码
之外,我获取所有内容的值。
这将向我表明原始字节没有使用NSUTF8编码进行格式化?

您是否尝试过使用类似的方式:

NSUInteger len = [imageData length];
Byte *byteData = (Byte*)malloc(len);
[imageData getBytes:&byteData length:len];
@implementation NSData (Base64)
- (NSString *)base64EncodedString
{
    return [self base64EncodedStringWithWrapWidth:0];
}
NSString *myString = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];
这将把您的NSData转换为base64字符串,而在另一端,您只需要对其进行解码

编辑:@Lucas说你可以这样做:

NSUInteger len = [imageData length];
Byte *byteData = (Byte*)malloc(len);
[imageData getBytes:&byteData length:len];
@implementation NSData (Base64)
- (NSString *)base64EncodedString
{
    return [self base64EncodedStringWithWrapWidth:0];
}
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;
    }
实施NSData(Base64) -(NSString*)base64EncodedString { 返回[self-base64EncodedStringWithWrapWidth:0]; } //辅助方法 -(NSString*)base64EncodedStringWithWrapWidth:(NSInteger)wrapWidth { //确保wrapWidth是4的倍数 愤怒宽度=(愤怒宽度/4)*4; const char lookup[]=“abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzo123456789+/”; 长输入长度=[自身长度]; const unsigned char*inputBytes=[self bytes]; long long maxOutputLength=(输入长度/3+1)*4; maxOutputLength+=wrapWidth?(maxOutputLength/wrapWidth)*2:0; 无符号字符*输出字节=(无符号字符*)malloc((NSUInteger)maxOutputLength); 龙龙我; 长输出长度=0; 对于(i=0;i>2]; outputBytes[outputLength++]=查找[(inputBytes[i]&0x03)>4]; outputBytes[outputLength++]=查找[(inputBytes[i+1]&0x0F)>6]; outputBytes[outputLength++]=查找[inputBytes[i+2]&0x3F]; //添加换行符 如果(wrapWidth&(outputLength+2)%(wrapWidth+2)==0) { outputBytes[outputLength++]='\r'; outputBytes[outputLength++]='\n'; } } //处理剩余数据 如果(i==输入长度-2) { //=终止符 outputBytes[outputLength++]=查找[(inputBytes[i]&0xFC)>>2]; outputBytes[outputLength++]=查找[(inputBytes[i]&0x03)>4]; outputBytes[outputLength++]=查找[(inputBytes[i+1]&0x0F)>2]; outputBytes[outputLength++]=查找[(inputBytes[i]&0x03)=4) { //截断数据以匹配实际输出长度 outputBytes=realloc(outputBytes,(NSInteger)outputLength); 返回[[NSString alloc]initWithBytesNoCopy:outputBytes 长度:(NSUTEGER)输出长度 编码:NSASCIIStringEncoding 弗里文登:是的; } else if(输出字节) { 空闲(输出字节); } 返回零; }
  • 在以前的堆栈文章中,字符串被视为“不可靠”的原因是,它们也试图使用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];
    
  • 你在正确的轨道上,希望这能帮助你解决目前的问题。祝你好运

    ~编辑~

    请确保您正在从图像中声明NSData对象,如下所示:

    NSData *imageData = [[NSData alloc] init];
    imageData = UIImagePNGRepresentation(yourImage);
    

    NSData
    转换为
    NSString
    时,空终止不是唯一的问题

    NSString
    不是为保存任意二进制数据而设计的。它需要编码

    如果您的
    NSData
    包含无效的
    UTF-8
    序列

    文档在这一点上并不完全清楚,但是对于
    initWithData
    ,它说:

    如果由于某种原因(例如)初始化失败,则返回nil 如果数据不表示编码的有效数据)

    另外:
    JSON
    规范将字符串定义为字符串

    这意味着,即使您能够将原始数据放入
    JSON
    字符串中,如果代码执行
    UTF-8
    验证,接收端的解析也可能失败


    如果您不想使用
    Base64
    ,。

    此答案中的所有代码都是伪代码片段,您需要自己将算法转换为Objective-C或其他语言。

    你的问题提出了许多问题……你从以下几点开始:

    我有一个NSData对象。我需要将其字节转换为字符串并作为JSON发送。description返回十六进制并且不可靠(根据各种SO海报)

    这似乎表明您希望将字节编码为字符串,准备将其解码回另一端的字节。如果是这种情况,您有许多选择,如Base-64编码等。如果您想要简单的东西,您可以将每个字节编码为其两个字符的十六进制值,伪代码大纲:

    NSMutableString *encodedString = @"".mutableCopy;
    foreach aByte in byteData
       [encodedString appendFormat:@"%02x", aByte];
    
    格式
    %02x
    表示两个带零填充的十六进制数字。这将生成一个字符串,该字符串可以作为JSON发送,并在另一端轻松解码。由于UTF-8是推荐的JSON有线编码,因此有线传输的字节大小可能是字节长度的两倍

    但是,在回答您所写的其中一个问题时:


    但我绝对需要那些未加工的东西

    你这么说是什么意思?你的接收者会把它得到的JSON字符串解释为