2017-10-05 50 views
0

我试图解析从以下POST请求的响应的POST响应:试图解析未知编码

// PERFORM REQUEST 
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 

    // GET RESPONSE STRING 
    responseStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; 

    // SIGNAL DONE 
    dispatch_semaphore_signal(sema); 

}]; 

我一直有特殊字符等问题ÀÈÌÒÙ返回错误。有没有一种方法可以确定数据的正确编码?或者用可以正确解释这些字符的东西解码数据?

+0

您可以检查是否有[[(NSHTTPURLResponse *)response allHeaderFields]'检查是否存在编码。 – Larme

+0

@Larme看起来没有任何编码相关的东西在标题 – Tony

回答

1

如果您有变音,NSASCIIStringEncoding绝对是错误的编码,这意味着原来的7位ASCII,将失败与价值的任何字节> 127

没有通用的方法来确定文本编码。根据您要下载的数据的不同,可能存在启发式。例如。如果您知道所有包含国际字符的响应中包含的字符串,则可以将该字节序列与各种编码中的字符序列进行比较。或者有些库包含某些字节序列的频率的统计信息,以检测文本是什么语言和编码,但这些都可能会猜测错误。

你已经在评论中说没有标题指示编码,这将是一个替代解决方案。

除此之外,您只能查看与您通话的任何服务器的规范,并硬编码给定的编码。或者如果没有,请尝试不同的编码,直到一个作品。

这些天最常见的编码是UTF8和Windows拉丁文1.如果直到很久以后才能说出(例如解析JSON响应),我推荐使用编码,其中0 ... 255是有效的(如Windows Latin或非有损ASCII),并在检查数据后,再次进行转换。

+0

谢谢你真的帮助找到解决方案。我能够将数据分成更小的部分,并分别搜索和解码每个块。 – Tony

0

我能够通过以下检测数据的编码来解决问题:

// FIND ENCODING 
NSStringEncoding encoding = [NSString stringEncodingForData:chunk encodingOptions:nil convertedString:nil usedLossyConversion:0]; 

为了提高它的准确性我了分割数据成块,并分别解码的每个块。用于执行此操作的代码如下所示:

// PERFORM REQUEST 
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 

    // INIT 
    responseStr = @""; 
    NSUInteger length = [data length]; 
    NSUInteger chunkSize = 100; 
    NSUInteger offset = 0; 

    do { 

     // GET CHUNK 
     NSUInteger thisChunkSize = length - offset > chunkSize ? chunkSize : length - offset; 
     NSData* chunk = [NSData dataWithBytesNoCopy:(char *)[data bytes] + offset 
              length:thisChunkSize freeWhenDone:NO]; 

     // SET OFFSET 
     offset += thisChunkSize; 

     // FIND ENCODING 
     NSStringEncoding encoding = [NSString stringEncodingForData:chunk encodingOptions:nil convertedString:nil usedLossyConversion:0]; 

     // GET RESPONSE STRING 
     NSString *chunkString = [[NSString alloc] initWithData:chunk encoding:encoding]; 

     // APPEND TO RESPONSE 
     responseStr = [responseStr stringByAppendingString:chunkString]; 

    } while (offset < length); 

    // SIGNAL DONE 
    dispatch_semaphore_signal(sema); 

}]; 
+0

我不确定将它分割是正确的解决方案......通常,启发式获取的文本越多,结果就越好(因为某些文本可能由在多种编码中有效且常见的模糊字节序列组成) - - 另外,你确定你的请求可以包含不同的编码吗?大多数API预先决定使用单一编码,并始终如一地使用它。 – uliwitness

+0

@uliwitness我正在访问的API可能包含多种语言的文本。我不确定是否有一种编码可以用于在相同规则下解码所有文本?或者问题在于AIP如何实施并且超出了我的控制范围?我理解,像我这样做可能会导致很多问题,但是我有点失落,不知道如何在不改变API的情况下改进它。 – Tony

+0

通常,如果它可能是多种语言,任何人在正确的思想(而不是向后兼容)都会使用Unicode编码,如UTF8,UTF16(大端或小端)或UTF32(大端或小端)。如果它不是Unicode并且不包含任何编码或使用CodePage的指示(ISO/Windows对不同的语言具有CodePages,这基本上只是编码的另一个名称,仅限于Windows/ISO家族的编码), API设计非常糟糕。 – uliwitness