代码之家  ›  专栏  ›  技术社区  ›  Bartłomiej Semańczyk

索引1超出界限[0。。0]创建NSAttributedString时

  •  1
  • Bartłomiej Semańczyk  · 技术社区  · 6 年前

    在我的代码中有一个扩展名 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:

    • 过滤咖啡50.00 x 1

    服务费:30.0

    当我们的工作人员开始准备您的订单时,您将收到一条消息。

    怎么了?;)

    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)
    

    2 回复  |  直到 6 年前
        1
  •  3
  •   ielyamani    6 年前

    此分机打开 NSAttributedString 为我工作字符串编码. :

    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")
    

    这是我在操场上用的一根绳子的延伸部分(从这里移植到斯威夫特4号) answer .):

    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
    
        2
  •  1
  •   Mohammed Abdullatif    6 年前

    我以前也遇到过类似的问题,我发现我在后台线程上运行我的逻辑。在我创建新的 NSAttributedString 实例,类似于您的行 let attributedString = try? NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil) . 你能确保你正在创建 NSAttributedString

    NSAttributedString documentation 有人说“不应该从后台线程调用HTML导入程序(即,options dictionary包含值为HTML的documentType)”,所以这可能会指导您解决问题。