一尘不染

无法将NSAttributedString.DocumentAttributeKey类型的值转换为.DocumentReadingOptionKey

swift

我在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”

我该如何解决?


阅读 382

收藏
2020-07-07

共1个答案

一尘不染

您需要传递可用的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

因此,为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导入。

2020-07-07