试图解析未知编码
我试图解析从以下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);
}];
我一直有特殊字符等问题À
È
Ì
Ò
Ù
返回错误。有没有一种方法可以确定数据的正确编码?或者用可以正确解释这些字符的东西解码数据?
如果您有变音,NSASCIIStringEncoding绝对是错误的编码,这意味着原来的7位ASCII,将失败与价值的任何字节> 127
没有通用的方法来确定文本编码。根据您要下载的数据的不同,可能存在启发式。例如。如果您知道所有包含国际字符的响应中包含的字符串,则可以将该字节序列与各种编码中的字符序列进行比较。或者有些库包含某些字节序列的频率的统计信息,以检测文本是什么语言和编码,但这些都可能会猜测错误。
你已经在评论中说没有标题指示编码,这将是一个替代解决方案。
除此之外,您只能查看与您通话的任何服务器的规范,并硬编码给定的编码。或者如果没有,请尝试不同的编码,直到一个作品。
这些天最常见的编码是UTF8和Windows拉丁文1.如果直到很久以后才能说出(例如解析JSON响应),我推荐使用编码,其中0 ... 255是有效的(如Windows Latin或非有损ASCII),并在检查数据后,再次进行转换。
谢谢你真的帮助找到解决方案。我能够将数据分成更小的部分,并分别搜索和解码每个块。 – Tony
我能够通过以下检测数据的编码来解决问题:
// 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);
}];
我不确定将它分割是正确的解决方案......通常,启发式获取的文本越多,结果就越好(因为某些文本可能由在多种编码中有效且常见的模糊字节序列组成) - - 另外,你确定你的请求可以包含不同的编码吗?大多数API预先决定使用单一编码,并始终如一地使用它。 – uliwitness
@uliwitness我正在访问的API可能包含多种语言的文本。我不确定是否有一种编码可以用于在相同规则下解码所有文本?或者问题在于AIP如何实施并且超出了我的控制范围?我理解,像我这样做可能会导致很多问题,但是我有点失落,不知道如何在不改变API的情况下改进它。 – Tony
通常,如果它可能是多种语言,任何人在正确的思想(而不是向后兼容)都会使用Unicode编码,如UTF8,UTF16(大端或小端)或UTF32(大端或小端)。如果它不是Unicode并且不包含任何编码或使用CodePage的指示(ISO/Windows对不同的语言具有CodePages,这基本上只是编码的另一个名称,仅限于Windows/ISO家族的编码), API设计非常糟糕。 – uliwitness
您可以检查是否有[[(NSHTTPURLResponse *)response allHeaderFields]'检查是否存在编码。 – Larme
@Larme看起来没有任何编码相关的东西在标题 – Tony