NSAttributedString extension in swift 3

2019-04-19 05:58发布

I'm migrating my code to swift 3 and I'm having a hard time with this extension that was working on the previous swift version.

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
    }
}

Now when I try to call this piece of code I get an exception error like this

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

That's how I call the method from my view controller

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

标签: ios swift swift3
2条回答
对你真心纯属浪费
2楼-- · 2019-04-19 06:15

In case anyone needs assist in Swift 4+ :

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
    }
}
查看更多
萌系小妹纸
3楼-- · 2019-04-19 06:39

Try this:

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
    }
}

As described in the official reference, the value for key NSCharacterEncodingDocumentAttribute needs to be an NSNumber.

NSCharacterEncodingDocumentAttribute

The value of this attribute is an NSNumber object containing integer specifying NSStringEncoding for the file;

In older Swifts, NSStringEncoding constants are imported as UInts, so they are automatically bridged to NSNumber when converted to AnyObject, as contained in NSDictionary.

But now, Swift introduced a new enum type String.Encoding which is not originated as an Objective-C enum. And unfortunately, now any Swift types can be contained in an NSDictionary with intermediate hidden reference type _SwiftValue, which definitely is NOT an NSNumber.

So, you need to pass something which can be bridged to NSNumber as the value for key NSCharacterEncodingDocumentAttribute. In your case, rawValue would work.

In my opinion, this should be improved, and better send a bug report to Apple or swift.org.

查看更多
登录 后发表回答