3

I am trying to convert HTML to NSAttributedString format and back. Converting from HTML works fine, however converting back to HTML gives me a format I cannot send to our backend:

<!DOCTYPE html PUBLIC -//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv=Content-Style-Type" content="text/css"> <title></title> <meta name="Generator" content="Cocoa HTML Writer"> <style type="text/css"> p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 15.0px; font: 16.0px 'Times New Roman'; color: #000000; -webkit-text-stroke: #000000} span.s1 {font-family: 'Times New Roman'; font-weight: normal; font-style: normal; font-size: 16.00pt; font-kerning: none} span.s2 {font-family: 'TimesNewRomanPS-BoldMT'; font-weight: bold; font-style: normal; font-size: 16.00pt; font-kerning: none} span.s3 {font-family: 'TimesNewRomanPS-ItalicMT'; font-weight: normal; font-style: italic; font-size: 16.00pt; font-kerning: none} span.s4 {font-family: 'TimesNewRomanPS-BoldItalicMT'; font-weight: bold; font-style: italic; font-size: 16.00pt; font-kerning: none} </style> </head> <body> <p class="p1"><span class="s1">vanlig text </span><span class="s2">bold</span><span class="s1"> </span><span class="s3">italic</span><span class="s1"> </span><span class="s4">bold_italic asd</span></p> </body> </html> 

The string/format I need to send my server cannot have css and needs to be something more like this: (without CSS)

<html> <body> <p>vanlig text <b>bold</b> <i>italic</i><b><i>bold_italic asd</i></b> </p> </body> </html> 

I've tried this solution without success: NSAttribute string to HTML I keeps the format with css.

My code so far:

extension NSAttributedString { var htmlString : String { let documentAttributes = [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType] if let htmlData = try? self.dataFromRange(NSMakeRange(0, self.length), documentAttributes:documentAttributes), let htmlString = String(data:htmlData, encoding:NSUTF8StringEncoding) { return htmlString } return "" } func attributedStringWithNoTrailingNewLines() -> NSMutableAttributedString { let mutableAttributedString = NSMutableAttributedString(attributedString: self) let nsString = string as NSString let lastWhitespaceOrNewlineRange = nsString.rangeOfCharacterFromSet(NSCharacterSet.whitespaceAndNewlineCharacterSet(), options: .BackwardsSearch) if lastWhitespaceOrNewlineRange.length != 0 && NSMaxRange(lastWhitespaceOrNewlineRange) == self.length { mutableAttributedString.replaceCharactersInRange(lastWhitespaceOrNewlineRange, withString: "") } return mutableAttributedString } } extension String { var attributedString : NSAttributedString? { if let data = self.dataUsingEncoding(NSUTF8StringEncoding) { let options = [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType] let attrStr = try? NSAttributedString(data: data, options: options, documentAttributes: nil) return attrStr } return nil } } 
7
  • Check this link stackoverflow.com/questions/37915304/…. i hope it will help to us. Commented Jun 22, 2016 at 9:03
  • I don't see how that's related. It only fixes whitespaces which isn't our problem. Commented Jun 22, 2016 at 9:08
  • 1
    Question: Your server can manage what tags exactly? Because in your sample, you gave "simples ones": <b><i>etc. If it's only "limited on", you could enumerate the attributed with effective range, and just add yourself the tags, and don't forget to add if necessary the "start" <html><body> and the end corresponding. Commented Jun 24, 2016 at 10:20
  • Yes. Have almost solved it and am doing it the way you proposed. Will post the code I used here after I'm finished. Commented Jun 27, 2016 at 11:02
  • 3
    Could you manage to do it? Commented Oct 26, 2016 at 15:14

2 Answers 2

2

I do not have the exact code I used to solve it, but I solved it by iterating the nsfontattributes and manually adding the supported html tags. Something like this in a NSAttributedString extension:

enumerateAttribute(NSFontAttributeName, inRange: NSMakeRange(0, length), options: NSAttributedStringEnumerationOptions(rawValue: 0)) { (value, range, stop) in if let font = value as? UIFont { var stringInRange = string.substringInRange(range) if font.isBold { stringInRange = "<b>\(stringInRange)</b>" } if font.isItalic { stringInRange = "<i>\(stringInRange)</i>" } // ... } } 
Sign up to request clarification or add additional context in comments.

2 Comments

but what if there is complex html?
Perhaps I missed to specify that in my question, but the app was only to support a limited number of html-features, such as bold, italic, numbered list and bullet lists.
1

I have good way to convert NSAttributedString into HTML string without CSS.

1) Take UIWebView and UITextView.

2) Set your Attributed string in WebView.

[webView loadHTMLString:[yourAttributedString stringByReplacingOccurrencesOfString:@"\n" withString:@"<br/>"] baseURL:nil]; 

3) Get your HTML string from UIWebView.

NSString *strExclusion = [webView stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML"]; 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.