2

I'm currently using this extension provided by this answer to convert html to strings within a UITextView. Everything works perfectly but for some strange reason the NSFontAttributeName is not applied to the string during the process. Is there something I'm doing wrong here? (or should I apply the NSAttributedString after reeving the attributed html parsed string? If so, is it possible to apply an attribute to an NSAttributeString? ).

PS. Font size is not change when using html2String but the links within the html is are longer recognized by the UITextView

extension String {

    var html2AttributedString: NSAttributedString? {
        guard
            let data = dataUsingEncoding(NSUTF8StringEncoding)
            else { return nil }
        do {
            return try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute:NSUTF8StringEncoding, NSFontAttributeName : UIFont.systemFontOfSize(17.0)], documentAttributes: nil)
        } catch let error as NSError {
            print(error.localizedDescription)
            return  nil
        }
    }
    var html2String: String {
        return html2AttributedString?.string ?? ""
    }
}
cell.desc.attributedText  = apiData[currentIndex].description!.html2AttributedString //Font attribute not recognized
cell.desc.text  = apiData[currentIndex].description!.html2String //Font recognized by links no longer recognized
Community
  • 1
  • 1
kye
  • 2,166
  • 3
  • 27
  • 41
  • That's normal behavior. `NSFontAttributeName` is not an allowed key for `options` parameter in `initWithData:options:documentsAttributes:error:`. You have to rewrite afterwards the font effect. So either you apply it by adding HTML into the original string, or afterwards (by that may remove the bold/italic effects). – Larme Apr 05 '16 at 14:11
  • Possible duplicate of [Apply Custom font to Attributed string Which Converts from HTML String](http://stackoverflow.com/questions/25401742/apply-custom-font-to-attributed-string-which-converts-from-html-string) – Larme Apr 05 '16 at 14:16
  • @Larme Thank you for these details, I had no idea this attribute was ignored in this method. I'm leaving my answer for OP in the case they decide to convert like this. – Eric Aya Apr 05 '16 at 14:19

2 Answers2

5

I'm not sure why (probably because of having a range) but it works if you first create an NSMutableAttributedString and then you add the UIFont attributes:

extension String {

    var html2AttributedString: NSMutableAttributedString? {
        guard
            let data = dataUsingEncoding(NSUTF8StringEncoding)
            else { return nil }
        do {
            let attrStr = try NSMutableAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute:NSUTF8StringEncoding], documentAttributes: nil)
            attrStr.addAttributes([NSFontAttributeName: UIFont.systemFontOfSize(17.0)], range: NSRange(location: 0, length: attrStr.length))
            return attrStr
        } catch let error as NSError {
            print(error.localizedDescription)
            return  nil
        }
    }
    var html2String: String {
        return html2AttributedString?.string ?? ""
    }
}
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
  • 1
    A little warning: If there is bold or italic effect in the HTML part, setting the font like this will remove it (since it's in the `UIFont`/`NSFontAttributeName` part). Reason why it's not working is because `NSFontAttributeName` is not a valid key (and ignored) in that init method. – Larme Apr 05 '16 at 14:15
  • 1
    Works perfectly thanks Eric! @Larme I will not be setting any bold or italic effects, this answer suits my needs. Thanks for the information – kye Apr 05 '16 at 14:23
  • @kye You're welcome. :) and thanks again Larme for the additional infos. – Eric Aya Apr 05 '16 at 14:25
  • 1
    @EricAya works perfectly. Thank you for the great answer! – donjordano Jul 06 '17 at 05:58
1

Here i have updated to SWIFT 3

extension String {

    var utf8Data: Data? {
        return data(using: .utf8)
    }
}

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

    var attributedStringHtml: NSMutableAttributedString? {
        do {
         let   attrStr = try NSMutableAttributedString(data: self, options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute:String.Encoding.utf8.rawValue], documentAttributes: nil)
            attrStr.addAttributes([NSFontAttributeName: UIFont.systemFont(ofSize: 17.0),NSForegroundColorAttributeName:UIColor.white], range: NSRange(location: 0, length: attrStr.length))
            return attrStr
        } catch let error as NSError {
            print(error.localizedDescription)
        }
        return nil
    }
}

Usage

 DispatchQueue.global(qos: .background).async {
            let attribut = self.sampleText.utf8Data?.attributedStringHtml
            DispatchQueue.main.async {
                self.convertedTextLbl.attributedText = attribut
            }
        }
karthikeyan
  • 3,821
  • 3
  • 22
  • 45