2

I have tried everything... Many articles and stackoverflow posts but I just can't seem to get it right. Scenario: I get back html code from a web service, very simple example is:

"<b>TEST</b>"

I convert this string to attributedString like this:

extension String {

var htmlToAttributedString: NSAttributedString? {
    guard let data = data(using: .utf8) else { return NSAttributedString() }
    do {
        return try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
    } catch {
        return NSAttributedString()
    }
  }
}

And then I display it like this:

self.textView.attributedText = htmlTextFromWebService.htmlToAttributedString

Perfect, my UITextView displays "TEST" as bold.

Now the problem: I am trying to send it back but the bold is gone. Here's how I'm doing that:

let attrString = NSAttributedString(string: self.textView.text)
var resultHtmlText = ""

 do {
        let r = NSRange(location: 0, length: attrString.length)
        let att = [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType]

        let data = try attrString.data(from: r, documentAttributes: att)

        if let h = String(data: data, encoding: .utf8) {

            resultHtmlText = h
        }
    } catch {
        print("FAILED TO CONVERT TO HTML")
    }

resultHtmlText is now:

<!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}
span.s1 {font-family: 'Helvetica'; font-weight: normal; font-style: normal; font-size: 12.00pt}
</style>
</head>
<body>
<p class="p1"><span class="s1">TEST</span></p>
</body>
</html>

But the web service cannot read this and plus, the bold tag is gone! So ultimately, how can I get resultHtmlText to be this:

"<b>TEST</b>"

I just want simple html tags as my result to send to the web service!

Thanks.

1

2 Answers 2

3

Maddy's answer identifies the narrow technical issue that your code was pulling the plain String from the text property of UITextView rather than the full NSAttributedString available from the attributedText property. That answer addresses the issue of your text losing the bold styling. If you correct your code as indicated, the bold styling will be preserved, but not in the manner that you desire. More specifically, the bold styling will be included in the style sheet portion of the header of the HTML document--it will not appear as an inline <b> tag.

However, your question is broader. If I may, the essence of your question is focussed on how to make a proper round trip with the HTML code? Without knowing more about your use case, I'm not sure I can fully answer that question. For what they are worth, I offer the following comments.


DISPLAYING HTML

If you have HTML code to display, the best way to do so in iOS is using a WKWebView, not a UITextView. There are LOTS of web view examples on StackOverflow and elsewhere, such as this tutorial.

For your use case, you'll want to use the loadHTMLString(:baseURL:) to insert the HTML code into the web view. A very stripped down example using the variable name from your code, as follows:

// ... embedded somewhere in a UIViewController
let webView = WKWebView()
self.view = webView
webView.loadHTMLString(htmlTextFromWebService, baseURL: nil)

EDITING HTML

If you also need to allow the user to edit the text, then you have a MUCH BIGGER TASK ahead of you. In that case, I suggest exploring GitHub for examples of attributed text editors built on WKWebView, like RichEditorView.


SENDING HTML CODE TO YOUR WEB SERVICE

Your example uses the NSAttributedString method data(from:documentAttributes:) to create an HTML code representation of an attributed string. That method creates a fully-formed HTML document, with a full header, and uses a style sheet in the header to provide the styling.

You state the the web service is unable to handle this text. I suspect your web service takes merely raw HTML code without the header, style sheet, etc. If so, the data(from:documentAttributes:) method isn't going to work for this purpose.

One solution is to avoid the round-trip conversion issues by working with the original HTML code at all times via WKWebView. See, above.

Another solution is to write your own, simple NSAttributedString-to-HTML parser. It seems like you might be using very simple text and styling. If so, the implementation of this sort of parser should be straightforward. If you need an example of that sort of parser, leave a comment, and I will provide some sample code.

Sign up to request clarification or add additional context in comments.

Comments

1

Change

let attrString = NSAttributedString(string: self.textView.text)

To

let attrString = self.textView.attributedText

This will give back the attributes but it will still give a full HTML result.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.