Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSAttributedString extension in swift 3

Tags:

ios

swift

swift3

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
like image 355
Ramon Vasconcelos Avatar asked Aug 31 '16 11:08

Ramon Vasconcelos


People also ask

What is NSAttributedString in Swift?

An NSAttributedString object manages character strings and associated sets of attributes (for example, font and kerning) that apply to individual characters or ranges of characters in the string. An association of characters and their attributes is called an attributed string.

How do you bold a string in Swift?

let normalFont = UIFont(name: "Dosis-Medium", size: 18) let boldSearchFont = UIFont(name: "Dosis-Bold", size: 18) self. UILabel. attributedText = addBoldText("Check again in 30 days to find more friends", boldPartsOfString: ["Check", "30 days", "find", "friends"], font: normalFont!, boldFont: boldSearchFont!)


2 Answers

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.

like image 181
OOPer Avatar answered Sep 27 '22 20:09

OOPer


In case anyone needs assistance in 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
    }
}
like image 24
Rafat touqir Rafsun Avatar answered Sep 27 '22 19:09

Rafat touqir Rafsun