在我的代码中,NSAttributedString
有一个扩展名:
internal convenience init?(html: String) {
guard let data = html.data(using: String.Encoding.utf8, allowLossyConversion: true) else {
return nil
}
print(UIKit.Thread.isMainThread) //TRUE
guard let attributedString = try? NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil) else { //here is the error
return nil
}
self.init(attributedString: attributedString)
}
然后我尝试像这样使用它:
let text = "<p>Your order has been created. </p><p>Below You can find the details of Your order:</p><p>Order ID: 183</p><p>Summary: <ul><li>Filtered coffee 50.00 x 1</li></ul></p><p>Service fee: 30.0</p><p>Total: 80.0 Kn</p><p>You will receive a message when our staff starts preparing Your order.<br/></p>"
let attributedString = NSAttributedString(html: text)
文本具有以下值:
Your order has been created.
Below You can find the details of Your order:
Order ID: 183
Summary:
Service fee: 30.0
Total: 80.0 Kn
You will receive a message when our staff starts preparing Your order.
怎么了?;)
编辑:
我将它与MessageKit一起使用以显示属性文本:
extension Message: MessageType {
var sender: Sender {
return Sender(id: createdBy?.identifier ?? "", displayName: createdBy?.name ?? "BOT_RESPONSE")
}
var messageId: String {
return identifier
}
var sentDate: Date {
return date
}
var kind: MessageKind {
guard let attributedString = NSAttributedString(html: text) else {
return .text(text)
}
return .attributedText(attributedString)
}
}
当我将断点放在出现错误的行上并在控制台上打印时:
po NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
那一切都很好;)为什么呢?
答案 0 :(得分:3)
NSAttributedString
上的此扩展名适用于String.Encoding。 utf16 :
extension NSAttributedString {
convenience init?(html: String) {
guard let data = html.data(using: String.Encoding.utf16, allowLossyConversion: false) else {
return nil
}
guard let attributedString = try? NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil) else {
return nil
}
self.init(attributedString: attributedString)
}
}
let text = "<p>Your order has been created. </p><p>Below You can find the details of Your order:</p><p>Order ID: 183</p><p>Summary: <ul><li>Filtered coffee 50.00 x 1</li></ul></p><p>Service fee: 30.0</p><p>Total: 80.0 Kn</p><p>You will receive a message when our staff starts preparing Your order.<br/></p>"
let attributedString = NSAttributedString(html: text)
print(attributedString ?? "Nothing")
这是String的扩展,在操场上对我有用(它从此answer移植到Swift 4。):
import Foundation
import UIKit
import PlaygroundSupport
let label = UILabel()
extension String {
func initFrom(html: String, with completionHandler: @escaping (NSAttributedString?) ->()) {
guard let data = html.data(using: String.Encoding.utf8, allowLossyConversion: true) else {
return completionHandler(nil)
}
let options: [NSAttributedString.DocumentReadingOptionKey : Any] = [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue]
DispatchQueue.main.async {
if let attributedString =
try? NSAttributedString(data: data, options: options, documentAttributes: nil)
{
completionHandler(attributedString)
} else {
completionHandler(nil)
}
}
}
}
let text = "<p>Your order has been created. </p><p>Below You can find the details of Your order:</p><p>Order ID: 183</p><p>Summary: <ul><li>Filtered coffee 50.00 x 1</li></ul></p><p>Service fee: 30.0</p><p>Total: 80.0 Kn</p><p>You will receive a message when our staff starts preparing Your order.<br/></p>"
text.initFrom(html: text, with: { attString in
print("attString =", attString ?? "")
label.attributedText = attString
})
PlaygroundPage.current.needsIndefiniteExecution = true
答案 1 :(得分:1)
我之前有一个类似的问题,我发现我在后台线程上运行逻辑。它在我创建新NSAttributedString
实例的行崩溃,类似于您的行let attributedString = try? NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
。您可以确定要在主线程上创建NSAttributedString
实例吗?
在NSAttributedString
documentation中,声明“不应从后台线程调用HTML导入器(即,选项字典包括值为html的documentType)”,因此,这也许可以为您提供一些指导找出问题所在。