Cocoa touch 从NSData创建NSString时猜测编码

Cocoa touch 从NSData创建NSString时猜测编码,cocoa-touch,cocoa,nsdata,Cocoa Touch,Cocoa,Nsdata,从文件中读取NSString时,我可以使用initWithContentsOfFile:usedEncoding:error:并猜测文件的编码 当我从一个NSData创建它时,尽管我唯一的选项是initWithData:encoding:其中我必须显式地传递编码。当我使用NSData而不是文件时,如何可靠地猜测编码?一般来说,你不能。但是,您可以非常可靠地识别UTF-8文件–如果文件是有效的UTF-8,那么它不太可能是任何其他编码(除非所有字节都在ASCII范围内,在这种情况下,任何“扩展ASC

从文件中读取
NSString
时,我可以使用
initWithContentsOfFile:usedEncoding:error:
并猜测文件的编码


当我从一个
NSData
创建它时,尽管我唯一的选项是
initWithData:encoding:
其中我必须显式地传递编码。当我使用
NSData
而不是文件时,如何可靠地猜测编码?

一般来说,你不能。但是,您可以非常可靠地识别UTF-8文件–如果文件是有效的UTF-8,那么它不太可能是任何其他编码(除非所有字节都在ASCII范围内,在这种情况下,任何“扩展ASCII”编码(包括UTF-8)都会给出相同的结果)。所有Unicode编码都有一个可选的标识。因此,合理的方法是:

  • 查找有效的BOM表。如果有,请使用适当的编码
  • 否则,尝试将其解释为UTF-8。您可以通过调用
    initWithData:data encoding:NSUTF8StringEncoding
    并检查结果是否为非nil来完成此操作
  • 如果失败,请使用默认的8位编码,例如
    -[NSString defaultCStringEncoding]
    (提供与区域设置相应的猜测)
可以通过尝试各种不同的编码来改进猜测,并选择中间有损坏的字母序列的一个,其中“垃圾”是任何字符,不是字母、空间或常用的标点符号。这将大大增加复杂性,但实际上并不可靠

简而言之,为了能够处理所有可用的编码,您需要做TextEdit所做的事情:将决策转移给用户


哦,还有一件事:从10.5开始,编码通常与一个文件一起存储在undocumented com.apple.textcodeding扩展属性中。如果打开的文件具有
+[NSString stringWithContentsOfFile::
或类似内容,则会自动使用该文件。

在iOS 8和OS X 10.10中,以下位置有一个新的API:

目标-C

+ (NSStringEncoding)stringEncodingForData:(NSData *)data
                          encodingOptions:(NSDictionary *)opts
                          convertedString:(NSString **)string
                      usedLossyConversion:(BOOL *)usedLossyConversion;
Swift

open class func stringEncoding(for data: Data,
                   encodingOptions opts: [StringEncodingDetectionOptionsKey : Any]? = nil, 
                 convertedString string: AutoreleasingUnsafeMutablePointer<NSString?>?, 
                    usedLossyConversion: UnsafeMutablePointer<ObjCBool>?) -> UInt

如果您只需要解码的字符串,而不关心编码,那么可以删除
让encoding=

看起来它还没有正式发布是有原因的。我使用PDF NSData编码运行它,它返回的是-2147482362。我不太确定它是否打算这样工作。pdf不是字符串,此方法从
NSData
中查找字符串的编码。你的目的是什么?我正在通过SDK检索pdf作为NSData。我现在在webview中显示它时遇到了一些问题,因为我不知道编码是什么,或者甚至不知道是否有编码。你看了答案了吗?如果这不起作用,我建议您在此处提出自己的问题,并提供有关您尝试过的内容、您的代码是什么以及哪些不起作用的详细信息。:)谢谢我已经修好了。原来我得到的是非pdf数据。
var convertedString: NSString?
let encoding = NSString.stringEncoding(for: data, encodingOptions: nil, convertedString: &convertedString, usedLossyConversion: nil)