Handling HTML Text Gaps in Swift

When working with HTML content in iOS applications, developers often encounter challenges in displaying text with the proper formatting, especially when it comes to maintaining the gaps or spaces between paragraphs. In this post, we are going to explore a simple solution to ensure your HTML text is displayed with the appropriate paragraph breaks, enhancing readability for your users.

The Issue

HTML content, especially when fetched from an API or hardcoded, might not always render with the expected formatting in a UITextView or a web view in Swift. One common issue is the disappearance of gaps between paragraphs, making the text appear as a single, bulky paragraph.

A Swift Solution

To tackle this, we can programmatically wrap each paragraph within <p> tags and ensure proper spacing is maintained. Let us dive into how we can achieve this with a straightforward Swift function.

Step 1: Define the Example HTML

First, let’s consider a sample HTML string that we want to format:

let exampleHTML = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularized in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.\r\n\r\n\r\nLorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s..."

Step 2: The Swift Function

The function wrapParagraphsInPTags takes a string of HTML and ensures each paragraph is enclosed in <p> tags, preserving the intended paragraph breaks.

func wrapParagraphsInPTags(_ html: String) -> String {
    let newlineCharacter: String
    if html.contains("\r\n") {
        newlineCharacter = "\r\n"
    } else {
        newlineCharacter = "\n"
    }

    let paragraphs = html.components(separatedBy: newlineCharacter)
    let wrappedParagraphs = paragraphs.map { "<p>\($0)</p>" }
    return wrappedParagraphs.joined(separator: newlineCharacter)
}

This function checks for the type of newline character used (\r\n or \n) and splits the HTML string into an array of paragraphs. Windows environment adds \r\n line breaks and macOS adds \n so both the scenarios have been handled. It then wraps each paragraph with <p> tags and joins them back together.

Step 3: Displaying the Formatted HTML

To display the formatted HTML content, we use an extension that converts the HTML string to an NSMutableAttributedString. This attributed string can then be displayed in a UITextView:

extension String {
    var htmlToAttributedString: NSMutableAttributedString? {
        guard let data = self.data(using: .utf8) else { return nil }
        do {
            return try NSMutableAttributedString(
                data: data,
                options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue],
                documentAttributes: nil
            )
        } catch {
            print("Error converting HTML to AttributedString: \(error)")
            return nil
        }
    }
}

And here’s how you can use it:

func displayAttributedText(from htmlString: String) {
    if let attributedString = htmlString.htmlToAttributedString {
        let textView = UITextView(frame: CGRect(x: 0, y: 0, width: 300, height: 500))
        textView.attributedText = attributedString
        PlaygroundPage.current.liveView = textView
    } else {
        print("No attributed string created")
    }
}

let wrappedHTML = wrapParagraphsInPTags(exampleHTML)
displayAttributedText(from: wrappedHTML)

Conclusion

With just a few lines of Swift, you can ensure your HTML content is displayed as intended, with clear, well-defined paragraph breaks that improve the readability of your content. Whether you are developing a blog reader app, a news aggregator, or any application that relies on rich text content, this simple technique can significantly enhance the presentation of your HTML content, making it more accessible and enjoyable for your users.