swiftswiftuiattributedstring

What Happened to NSAttributedString in Swift 5? Bold Doesnt work?


All the sample code i have comea cross with just does not work with bold tags anymore. This also include italic html tags.

I am using the code from hacking swift as string extension.

var htmlAttributedString: NSAttributedString? {
        if let attributedString = try? NSAttributedString(data: Data(self.utf8), options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil) {
            return attributedString
        }
        else {
            return nil
        }
    }
    
    var htmlString: String {
        return htmlAttributedString?.string ?? ""
    }

Then try

let string = "<b>sample</b>"
Text(string.htmlString)

The code looks about right. Just that the bold tag does not get rendered. Anyone know of a workaround? I tried the adding html style system hardcoding font trick but it did not work as well.

I tried the markdown alternative , no luck either (but this is a different topic).


Solution

  • Note that your htmlString property essentially converts the attributed string back to a plain text string. Accessing the NSAttributedString.string property gives you the plain text parts of the string back, without any attributes.

    Since this string is to be displayed in a Text, you can use the Swift AttributedString API instead. Change the type of htmlAttributedString to AttributedString, and convert the NSAttributedString:

    extension String {
        var htmlAttributedString: AttributedString {
            if let attributedString = try? NSAttributedString(data: Data(self.utf8), options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil) {
                return AttributedString(attributedString)
            }
            else {
                return ""
            }
        }
    }
    

    Then you can create the Text like this:

    Text("<b>foo</b>bar".htmlAttributedString)
    

    Side note: if you are working with markdown instead, you can directly create the Text using a string literal like this - no need for any AttributedStrings

    Text("**foo** bar")
    

    If your markdown string is not a literal, wrap it in a LocalizedStringKey:

    Text(LocalizedStringKey(someMarkdown))