25

-[NSMutableAttributedString initWithHTML:documentAttributes:]似乎破坏了特殊字符:

NSString *html = @"“Hello” World"; // notice the smart quotes
NSData *htmlData = [html dataUsingEncoding:NSUTF8StringEncoding];
NSMutableAttributedString *as = [[NSMutableAttributedString alloc] initWithHTML:htmlData documentAttributes:nil];
NSLog(@"%@", as);

打印“Hello†World后跟一些 RTF 命令。在我的应用程序中,我将属性字符串转换为 RTF 并将其显示在 中NSTextView,但那里的字符也已损坏。

根据文档,默认编码是 UTF-8,但我尝试显式,结果是一样的:

NSDictionary *attributes = @{NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]};
NSMutableAttributedString *as = [[NSMutableAttributedString alloc] initWithHTML:htmlData documentAttributes:&attributes];
4

3 回答 3

36

[html dataUsingEncoding:NSUnicodeStringEncoding]在创建 NSData 并在将 HTML 解析为属性字符串时设置匹配编码选项时使用:

的文档NSCharacterEncodingDocumentAttribute有点令人困惑:

NSNumber,包含一个指定NSStringEncoding文件的 int;用于读取和写入纯文本文件和编写 HTML;纯文本的默认值是默认编码;HTML 的默认值为 UTF-8。

所以,你的代码应该是:

NSString *html = @"“Hello” World";
NSData *htmlData = [html dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
                                    NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)};
NSMutableAttributedString *as =
    [[NSMutableAttributedString alloc] initWithHTML:htmlData
                                            options: options
                                 documentAttributes:nil];
于 2013-04-11T19:42:07.990 回答
10

这里之前的答案有效,但主要是偶然的。

使用NSDatawithNSUnicodeStringEncoding往往会起作用,因为该常量是 的别名NSUTF16StringEncoding,并且 UTF-16 很容易被系统识别。比 UTF-8 更容易,后者显然被识别为 ASCII 的其他超集(NSWindowsCP1252StringEncoding在您的情况下看起来像,可能是因为它是为数不多的具有 0x8_ 和 0x9_ 映射的基于 ASCII 的编码之一)。

这个答案在引用文档时是错误的NSCharacterEncodingDocumentAttribute,因为“属性”是你从中得到-initWithHTML。这就是为什么它是NSDictionary **而不只是NSDictionary *。您可以传入一个指向 的指针NSDictionary *,然后您将得到诸如 TopMargin/BottomMargin/LeftMargin/RightMargin、PaperSize、DocumentType、UTI 等键。您尝试通过“属性”字典传入的任何值都将被忽略。

您需要使用“选项”来传递值并且相关的选项键是NSTextEncodingNameDocumentOption,它没有记录的默认值。它将字节传递给 WebKit 进行解析,所以如果你不指定编码,大概你得到的是 WebKit 的编码猜测启发式。

NSData为了保证你的和之间的编码类型匹配NSAttributedString,你应该做的是:

NSString *html = @"“Hello” World";
NSData *htmlData = [html dataUsingEncoding:NSUTF8StringEncoding];

NSMutableAttributedString *as =
    [[NSMutableAttributedString alloc] initWithHTML:htmlData
                                            options:@{NSTextEncodingNameDocumentOption: @"UTF-8"}
                                 documentAttributes:nil];
于 2014-02-19T22:42:29.543 回答
10

接受答案的 Swift 版本是:

let htmlString: String = "Hello world contains html</br>"
let data: Data = Data(htmlString.utf8)

let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
    .documentType: NSAttributedString.DocumentType.html,
    .characterEncoding: String.Encoding.utf8.rawValue
]

let attributedString = try? NSAttributedString(data: data,
    options: options,
    documentAttributes: nil)
于 2020-04-04T13:20:27.700 回答