我在SO的某处找到了此字符串扩展名,它使我可以将html代码转换为属性字符串:
func html2AttributedString() -> NSAttributedString { return try! NSAttributedString(data: self.data(using: String.Encoding.unicode, allowLossyConversion: true)!, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) }
在Swift 3中工作正常,但在Swift 4中,Xcode抱怨:
无法将类型“ NSAttributedString.DocumentAttributeKey”的值转换为预期的字典密钥类型“ NSAttributedString.DocumentReadingOptionKey”
我该如何解决?
您需要传递可用的NSAttributedString DocumentType选项之一:
超文本标记语言(HTML)文档。
static let html: NSAttributedString.DocumentType
纯文本文档。
static let plain: NSAttributedString.DocumentType
富文本格式的文档。
static let rtf: NSAttributedString.DocumentType
带附件文档的RTF格式。
static let rtfd: NSAttributedString.DocumentType
在这种情况下,您将需要通过第一个(html) NSAttributedString.DocumentType.html
NSAttributedString.DocumentType.html
因此,为Swift 4 的扩展应如下所示:
extension NSAttributedString { convenience init(data: Data, documentType: DocumentType, encoding: String.Encoding = .utf8) throws { try self.init(data: data, options: [.documentType: documentType, .characterEncoding: encoding.rawValue], documentAttributes: nil) } convenience init(html data: Data) throws { try self.init(data: data, documentType: .html) } convenience init(txt data: Data) throws { try self.init(data: data, documentType: .plain) } convenience init(rtf data: Data) throws { try self.init(data: data, documentType: .rtf) } convenience init(rtfd data: Data) throws { try self.init(data: data, documentType: .rtfd) } }
extension StringProtocol { var data: Data { return Data(utf8) } var htmlToAttributedString: NSAttributedString? { do { return try .init(html: data) } catch { print("html error:", error) return nil } } var htmlDataToString: String? { return htmlToAttributedString?.string } }
extension Data { var htmlToAttributedString: NSAttributedString? { do { return try .init(html: self) } catch { print("html error:", error) return nil } } }
游乐场测试
let htmlString = "<style type=\"text/css\">#red{color:#F00}#green{color:#0F0}#blue{color: #00F; font-weight: Bold; font-size: 32}</style><span id=\"red\" >Red</span><span id=\"green\" > Green </span><span id=\"blue\">Blue</span>" let htmlData = Data(htmlString.utf8) htmlString.htmlToAttributedString htmlData.htmlToAttributedString
讨论不应从后台线程调用HTML导入器(即,选项字典包含值为html的documentType)。它将尝试与主线程同步,失败并超时。从主线程调用它是可行的(但如果HTML包含对外部资源的引用,仍可能会超时,应该不惜一切代价避免这样做)。HTML导入机制用于实现诸如markdown之类的东西(即,文本样式,颜色等),而不是用于常规HTML导入。