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

问题描述 投票:34回答:7

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

我该如何解决?

ios swift swift4 nsattributedstringkey
7个回答
87
投票

您需要传递一个可用的NSAttributedString DocumentType选项:


超文本标记语言(HTML)文档。

static let html: NSAttributedString.DocumentType

纯文本文档。

static let plain: NSAttributedString.DocumentType

富文本格式文档。

static let rtf: NSAttributedString.DocumentType

带附件文档的富文本格式。

static let rtfd: NSAttributedString.DocumentType

在这种情况下,您需要传递第一个(html)NSAttributedString.DocumentType.html

所以扩展updated到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导入


18
投票

有这个后自动转换为Swift 4.通过改变来修复:

NSMutableAttributedString(data: data, 
   options: [NSAttributedString.DocumentAttributeKey.documentType : NSAttributedString.DocumentType.html], 
   documentAttributes: nil)

至:

NSMutableAttributedString(data: data,
   options: [.documentType : NSAttributedString.DocumentType.html],
   documentAttributes: nil) {

12
投票

这对我有用:

let attrStr = try! NSAttributedString(
    data: modifiedFont.data(using: .unicode, allowLossyConversion: true)!,
    options:[.documentType: NSAttributedString.DocumentType.html,
    .characterEncoding: String.Encoding.utf8.rawValue],
    documentAttributes: nil)

如果你不添加

.characterEncoding:String.Encoding.utf8.rawValue

该应用程序将崩溃。


4
投票

对于HTML字符串,NSAttributedString.DocumentType.html是正确的选项。

Swift 4

extension String {

    var utfData: Data? {
        return self.data(using: .utf8)
    }

    var htmlAttributedString: NSAttributedString? {
        guard let data = self.utfData else {
            return nil
        }
        do {
            return try NSAttributedString(data: data,
           options: [
                     NSAttributedString.documentType: NSAttributedString.DocumentType.html,
                     NSAttributedString.characterEncoding: String.Encoding.utf8.rawValue
                    ], documentAttributes: nil)
        } catch {
            print(error.localizedDescription)
            return nil
        }
    }
}

2
投票

swift 4:我不知道为什么,但所有答案都有编译错误。所以我使用这个扩展:

extension String {
    var html2AttributedString: NSAttributedString? {
        do {
            return try NSAttributedString(data: data(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue))!,
                                          options: [.documentType: NSAttributedString.DocumentType.html,
                                                    .characterEncoding: String.Encoding.utf8.rawValue],
                                          documentAttributes: nil)
        } catch {
            print("error: ", error)
            return nil
        }
    }
    var html2String: String {
        return html2AttributedString?.string ?? ""
    }
}

如何使用 ?

mylable.text = htmlVariable.html2String


0
投票

我使用NSAttributedStringKey并在Swift 4上有类似的错误“无法转换类型的值”。万一使用NSAttributedStringKey的人来这里寻找答案,这就是我修复的方法:

let TextStroke: [NSAttributedStringKey : Any] = [
    NSAttributedStringKey(rawValue: NSAttributedStringKey.strokeColor.rawValue) : UIColor.black,
    NSAttributedStringKey(rawValue: NSAttributedStringKey.foregroundColor.rawValue) : UIColor.white,
    NSAttributedStringKey(rawValue: NSAttributedStringKey.strokeWidth.rawValue) : -6.0,]

这就是我将该属性添加到文本中的方式:

myLabel.attributedText = NSAttributedString(string: myString, attributes: TextStroke)

0
投票

使用NSAttributedString.DocumentType.html

NSMutableAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html] , documentAttributes: nil)
© www.soinside.com 2019 - 2024. All rights reserved.