I have an NSAttributed
string (coming from HTML) that I set for a UITextView
.
- (void)setHtml:(NSString *)html {
NSData *htmlData = [html dataUsingEncoding:NSUTF8StringEncoding];
// Create the HTML string
NSDictionary *importParams = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSError *error = nil;
self.htmlString = [[NSAttributedString alloc] initWithData:htmlData options:importParams documentAttributes:NULL error:&error];
self.editorView.attributedText = self.htmlString;
}
I then let the user edit what they want, and I would like to then convert it out to HTML again, so I use:
- (NSString *)getHTML {
NSDictionary *exportParams = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSData *htmlData = [self.editorView.attributedText dataFromRange:NSMakeRange(0, self.editorView.attributedText.length) documentAttributes:exportParams error:nil];
return [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
}
It does return HTML, but it isn't how I want it. Everything is given a class attribute, and the CSS it put at the top of the document. Things like images and links are not even included in the returned HTML and probably tons more issues.
Is there a better way to get HTML from an NSAttributedString
? Or, is there a way I could parse the NSAttributedString
and write my own HTML?
This is a complex issue, and I will start with a shorter answer. You may ask me questions in the comments, and I will expand on the answer as needed.
We also tried to go the attributed string route, but found it not suited for full HTML editing. Many elements are just not supported, either because the converter is not fully developed, or these elements were deemed outside of scope by Apple. Parsing the attributed string is not good enough, because the attributed string has already lost most of the richness of the HTML by the time you attempt to recreate it.
Instead, we use a webview, load the document normally, and enable
contentEditable
on the body element. What this does is allow editing of the document in its fullest, limited only by WebKit. At the end, to retrieve the HTML back, we disablecontentEditable
and take thedocument.outerHTML
to get an entire HTML as it was before, with changes made by the user.Don't take the decision to implement this method lightly. It is a somewhat complex solution, but certainly possible. A webview is not as nice as a textview, but it can be, given enough massage.
I will expand on this answer as needed.