Skip to content

Strings and Characters

Swift's String and Character types provide a robust, Unicode-compliant way to work with text. Strings are represented by the String type, which is a collection of Character values. This document covers the essentials of creating, manipulating, and accessing strings in Swift, with simplified examples.

String Literals

A string literal is a sequence of characters enclosed in double quotation marks (").

swift
let greeting = "Hello, Swift!"

Swift infers the String type for greeting because it’s initialized with a string literal.

Multiline String Literals

For strings spanning multiple lines, use a multiline string literal with three double quotation marks ("""):

swift
let multiLine = """
Welcome to Swift programming.
This is a multiline string.
It spans several lines.
"""

The string starts on the first line after the opening """ and ends on the line before the closing """, excluding line breaks at the start or end unless explicitly included.

To include line breaks in the source code without affecting the string’s value, use a backslash (\) at the end of a line:

swift
let noLineBreaks = """
Line one ends here. \
Line two continues without a break.
"""

To include a line break at the start or end, add a blank line:

swift
let withLineBreaks = """

This starts with a line break.
It ends with one too.

"""

Indentation in multiline strings is handled by matching the whitespace before the closing """. Extra indentation beyond this is included in the string.

Special Characters in String Literals

String literals support special characters:

  • Escaped characters: \0 (null), \\ (backslash), \t (tab), \n (line feed), \r (carriage return), \" (double quote), \' (single quote).
  • Unicode scalars: \u{n}, where n is a 1–8 digit hexadecimal number.

Examples:

swift
let quote = "\"Swift is fun!\" - Developer"
let currency = "\u{24}"        // $
let heart = "\u{2665}"         // ♥
let star = "\u{1F31F}"         // 🌟

In multiline strings, include a double quote (") without escaping, but escape at least one quote to include """:

swift
let multiQuotes = """
A single quote: "
All three quotes: \"\"\"
"""

Extended String Delimiters

Use extended delimiters (#) to include special characters without their effect:

swift
let rawString = #"No newline: \n"#

For interpolation within extended delimiters, match the number of # symbols:

swift
let calc = #"Result: \#(2 + 3)"#  // Prints "Result: 5"

Initializing an Empty String

Create an empty string using an empty literal or initializer:

swift
var empty = ""
var anotherEmpty = String()

Check if a string is empty with the isEmpty property:

swift
if empty.isEmpty {
    print("String is empty")
}

String Mutability

Strings are mutable when assigned to a variable (var) and immutable when assigned to a constant (let):

swift
var mutable = "Swift"
mutable += " Programming"
// mutable is now "Swift Programming"

let constant = "Code"
// constant += " More" // Error: cannot modify a constant

Strings as Value Types

Swift’s String is a value type, meaning it’s copied when assigned or passed to a function. The compiler optimizes copying to occur only when necessary, ensuring good performance.

Working with Characters

Iterate over a string’s characters with a for-in loop:

swift
for char in "Swift!" {
    print(char)
}
// Prints:
// S
// w
// i
// f
// t
// !

Create a Character from a single-character string literal:

swift
let star: Character = "*"

Construct a string from an array of characters:

swift
let chars: [Character] = ["S", "w", "i", "f", "t"]
let swiftString = String(chars)  // "Swift"

Concatenating Strings and Characters

Concatenate strings with the + operator or append with +=:

swift
let part1 = "Hello"
let part2 = " World"
var combined = part1 + part2  // "Hello World"
combined += "!"  // "Hello World!"

Append a character with the append(_:) method:

swift
combined.append("*")  // "Hello World!*"

Ensure multiline strings end with a line break for consistent concatenation:

swift
let start = """
First line
Second line

"""
let end = """
Third line
"""
print(start + end)
// Prints:
// First line
// Second line
// Third line

String Interpolation

Insert values into a string using \(expression):

swift
let number = 5
let text = "\(number) doubled is \(number * 2)"
// text is "5 doubled is 10"

With extended delimiters, match the number of # symbols for interpolation:

swift
print(#"Value: \#(number * 2)"#)  // Prints "Value: 10"

Unicode

Swift’s String and Character types are Unicode-compliant. A Character represents an extended grapheme cluster, combining one or more Unicode scalars into a single human-readable character.

Examples:

swift
let eAcute: Character = "\u{E9}"              // é
let combinedEAcute: Character = "\u{65}\u{301}"  // e + combining acute accent

Both represent the same Character (é).

Counting Characters

Use the count property to get the number of characters:

swift
let text = "Swift 🐦 Code"
print(text.count)  // Prints 11

Combining scalars (e.g., e + U+0301) doesn’t increase the character count:

swift
var word = "code"
word += "\u{301}"  // Adds combining acute accent
print(word.count)  // Still 4

Accessing and Modifying Strings

Use String.Index to access characters, as Swift strings can’t use integer indices due to variable memory requirements for Unicode characters.

Access characters:

swift
let text = "Swift Code"
print(text[text.startIndex])  // S
print(text[text.index(before: text.endIndex)])  // e
print(text[text.index(text.startIndex, offsetBy: 2)])  // i

Insert characters or strings:

swift
var text = "Swift"
text.insert("!", at: text.endIndex)  // "Swift!"
text.insert(contentsOf: " is", at: text.index(before: text.endIndex))  // "Swift is!"

Remove characters or substrings:

swift
text.remove(at: text.index(before: text.endIndex))  // "Swift is"
let range = text.index(text.endIndex, offsetBy: -3)..<text.endIndex
text.removeSubrange(range)  // "Swift"

Substrings

Substrings, obtained via methods like prefix(_:) or subscripts, are of type Substring. Convert to String for long-term storage:

swift
let greeting = "Hello, Swift!"
let index = greeting.firstIndex(of: ",") ?? greeting.endIndex
let substring = greeting[..<index]  // "Hello"
let newString = String(substring)  // Convert to String

Substrings reuse the original string’s memory, optimizing performance but requiring conversion for persistence.

Comparing Strings

Compare strings with == and != for canonical equivalence:

swift
let text1 = "café"
let text2 = "caf\u{65}\u{301}"
print(text1 == text2)  // true

Check prefixes and suffixes with hasPrefix(_:) and hasSuffix(_:):

swift
let scenes = [
    "Scene 1: Park",
    "Scene 2: Cafe",
    "Scene 3: Park View"
]
var parkCount = 0
for scene in scenes {
    if scene.hasPrefix("Scene ") {
        parkCount += 1
    }
}
print("Scenes: \(parkCount)")  // Prints "Scenes: 3"

Unicode Representations

Access Unicode representations of a string:

  • UTF-8: utf8 property (8-bit code units).
  • UTF-16: utf16 property (16-bit code units).
  • Unicode Scalars: unicodeScalars property (21-bit values).

Example:

swift
let text = "Swift🌟"
for code in text.utf8 {
    print("\(code) ", terminator: "")
}
// Prints: 83 119 105 102 116 240 159 140 159

Released under the MIT License.