Расширение NSAttributedString в Swift 3

Я переношу свой код на Swift 3, и мне трудно работать с этим расширением, которое работало над предыдущей версией Swift.

extension Data {
    var attributedString: NSAttributedString? {
        do {
            return try NSAttributedString(data: self, options:[NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8], documentAttributes: nil)
        } catch let error as NSError {
            print(error.localizedDescription)
        }
        return nil
    }
}

Теперь, когда я пытаюсь вызвать этот фрагмент кода, я получаю ошибку исключения, подобную этой

error: warning: couldn't get required object pointer (substituting NULL): Couldn't load 'self' because its value couldn't be evaluated

Вот как я вызываю метод из моего контроллера представления

let htmlCode = "<html><head><style type=\"text/css\">@font-face {font-family: Avenir-Roman}body {font-family: Avenir-Roman;font-size:15;margin: 0;padding: 0}</style></head><body bgcolor=\"#FBFBFB\">" + htmlBodyCode + "</body>"
newsDescription.attributedText = htmlCode.utf8Data?.attributedString

person Ramon Vasconcelos    schedule 31.08.2016    source источник


Ответы (2)


Попробуй это:

extension Data {
    var attributedString: NSAttributedString? {
        do {
            return try NSAttributedString(data: self, options:[NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue], documentAttributes: nil)
        } catch let error as NSError {
            print(error.localizedDescription)
        }
        return nil
    }
}

Как описано в официальном справочнике, значение ключа NSCharacterEncodingDocumentAttribute должно быть NSNumber.

NSCharacterEncodingDocumentAttribute

Значением этого атрибута является объект NSNumber, содержащий целое число, указывающее NSStringEncoding для файла;

В старых Swift константы NSStringEncoding импортируются как UInt, поэтому они автоматически соединяются с NSNumber при преобразовании в AnyObject, как содержится в NSDictionary.

Но теперь Swift представил новый тип перечисления String.Encoding, который не был создан как перечисление Objective-C. И, к сожалению, теперь любые типы Swift могут содержаться в NSDictionary с промежуточным скрытым ссылочным типом _SwiftValue, который определенно НЕ является NSNumber.

Итак, вам нужно передать что-то, что может быть соединено с NSNumber в качестве значения для ключа NSCharacterEncodingDocumentAttribute. В вашем случае подойдет rawValue.

На мой взгляд, это следует улучшить, и лучше отправить отчет об ошибке в Apple или swift.org.

person OOPer    schedule 31.08.2016
comment
Спасибо! Однако, поскольку я использовал модифицированный шрифт, мне пришлось добавить еще одну уловку: поймать ошибку NSError {print(error.localizedDescription)} catch {print(Description Error)} - person thejuki; 16.01.2017

Если кому-то нужна помощь в Swift 5.2+:

extension Data {
    var attributedString: NSAttributedString? {
        do {
            return try NSAttributedString(data: self, options: [ NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html, NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue ], documentAttributes: nil)
        } catch let error as NSError {
            print(error.localizedDescription)
        }
        return nil
    }
}
person Rafat touqir Rafsun    schedule 05.07.2017