Swift
HTML entities
decode
programming
tutorial

How do I decode HTML entities in Swift?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

HTML entities such as &, ", and ' often appear in text coming from feeds, APIs, or stored HTML fragments. In Swift, the usual goal is to turn those encoded sequences back into readable characters without manually replacing every entity by hand.

A Practical Approach with NSAttributedString

The most common Foundation-based solution is to let NSAttributedString parse a short HTML fragment and then read its plain string value. This handles named entities and numeric entities in one step.

swift
1import Foundation
2
3extension String {
4    var htmlDecoded: String {
5        guard let data = Data(self.utf8) else { return self }
6
7        let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
8            .documentType: NSAttributedString.DocumentType.html,
9            .characterEncoding: String.Encoding.utf8.rawValue
10        ]
11
12        return (try? NSAttributedString(
13            data: data,
14            options: options,
15            documentAttributes: nil
16        ).string) ?? self
17    }
18}
19
20let encoded = "Tom & Jerry 'Greatest Hits'"
21print(encoded.htmlDecoded)

Output:

text
Tom & Jerry 'Greatest Hits'

This works well for common iOS and macOS code where Foundation is already available.

Why This Works Better Than Manual Replacement

A hand-written replacement table can decode a few common entities, but it quickly becomes incomplete. HTML supports many named entities and numeric forms such as decimal and hexadecimal references. NSAttributedString already understands those rules, so you do not have to keep your own lookup table in sync.

It also avoids bugs where replacement order matters. For example, replacing & too early can accidentally change other entity sequences before they are fully decoded.

Be Aware That This Parses HTML, Not Just Entities

There is an important side effect. The HTML parser does more than decode entities. It also interprets tags.

For example:

swift
let text = "<b>Hello</b> &amp; welcome"
print(text.htmlDecoded)

The result is:

text
Hello & welcome

That may be exactly what you want for display text, but it is different from a pure entity decoder that leaves markup untouched. If you need to preserve literal tags, use a dedicated parser or a narrower decoding strategy.

A Small Helper for Reuse

Wrapping the logic in a string extension keeps view code clean and makes the behavior easy to test. It also gives you a single place to change the implementation later if your project needs stricter handling.

For example, if the app starts decoding thousands of strings per screen, you may decide to cache results or move parsing off a hot path. A well-named extension makes that refactor easier.

When a Manual Map Is Acceptable

If you know the input contains only a tiny set of entities, a manual replacement function can be acceptable:

swift
1func decodeBasicEntities(_ text: String) -> String {
2    return text
3        .replacingOccurrences(of: "&amp;", with: "&")
4        .replacingOccurrences(of: "&quot;", with: "\"")
5        .replacingOccurrences(of: "&#39;", with: "'")
6}

This is simple, but it should be treated as a narrow shortcut, not a general HTML entity decoder.

Common Pitfalls

The first pitfall is double decoding. If a string has already been decoded once, running it through another decoder can change content unexpectedly.

Another mistake is using HTML parsing when you needed to preserve raw tags. NSAttributedString is convenient, but it interprets markup as structure, not as literal text.

Malformed or partial HTML can also produce results you did not expect. If the input is unreliable, keep the fallback path that returns the original string when parsing fails.

Finally, avoid large manual replacement tables unless you have a very controlled input format. They are easy to start and tedious to keep correct.

Summary

  • A common Swift solution is to decode HTML entities by parsing the text with NSAttributedString.
  • This handles named and numeric entities without maintaining a large manual map.
  • The method also interprets HTML tags, so it is best for display text rather than raw markup preservation.
  • A small string extension makes the behavior easy to reuse and test.
  • Manual replacement is acceptable only for a very small, well-defined set of entities.

Course illustration
Course illustration

All Rights Reserved.