swift - 如何使 NSAttributedString 可编码兼容?

标签 swift codable

问题是什么?

目前我正在我的主应用程序上构建一个应用程序扩展,它通过 JSON 进行通信。主题和数据位于 JSON 中,并通过 Apple 的可编码协议(protocol)进行解析。我现在遇到的问题是使 NSAttributedString 可编码兼容。我知道它不是内置的,但我知道它可以转换为数据并返回 .

到目前为止我有什么?

将 NSAttributedString 转换为数据以便通过 JSON 共享它。

if let attributedText = something.attributedText {
    do {
        let htmlData = try attributedText.data(from: NSRange(location: 0, length: attributedText.length), documentAttributes: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType])
        let htmlString = String(data: htmlData, encoding: .utf8) ?? "" 
    } catch {
        print(error)
    }
}

将 html JSON 字符串转换回 NSAttributedString:

do {
    return try NSAttributedString(data: self, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
} catch {
    print("error:", error)
    return  nil
}

我的问题?

How to make a struct that has a property nsAttributedTitle which is of type NSAttributedString and make it codable compliant with custom encoder decoder?

结构示例(不考虑可编码合规性):

struct attributedTitle: Codable {
    var title: NSAttributedString

    enum CodingKeys: String, CodingKey {
        case title
    }

    public func encode(to encoder: Encoder) throws {}
    public init(from decoder: Decoder) throws {}
}

最佳答案

NSAttributedString 符合 NSCoding,因此您可以使用 NSKeyedArchiver 获取 Data 对象。

这是一个可能的解决方案

class AttributedString : Codable {
    
    let attributedString : NSAttributedString
    
    init(nsAttributedString : NSAttributedString) {
        self.attributedString = nsAttributedString
    }
    
    public required init(from decoder: Decoder) throws {
        let singleContainer = try decoder.singleValueContainer()
        guard let attributedString = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(singleContainer.decode(Data.self)) as? NSAttributedString else {
            throw DecodingError.dataCorruptedError(in: singleContainer, debugDescription: "Data is corrupted")
        }
        self.attributedString = attributedString
    }
    
    public func encode(to encoder: Encoder) throws {
        var singleContainer = encoder.singleValueContainer()
        try singleContainer.encode(NSKeyedArchiver.archivedData(withRootObject: attributedString, requiringSecureCoding: false))
    }
}

更新:

在 Swift 5.5 中引入了符合 Codable 的原生 AttributedString

关于swift - 如何使 NSAttributedString 可编码兼容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54124396/

相关文章:

ios - Swift - 带有两行文本的 UIButton

Swift:添加方向按钮以固定注释

ios - 使用 Codable 解析 json 数据

ios - 使用 Codable 协议(protocol)按照从服务器接收到的相同顺序解码 json

json - 解析 JSON 的 SWIFT 模型

Swift 4 - Codable - 解码时如何允许 key 的不同对象类型

swift - 将可解析结构转换为可编码结构无法按预期工作

ios - 在单元格内显示整个表格 View

javascript - iOS 设备的远程访问

ios - 发送 HTTP POST 请求时后台模式出现问题