Values and types
Strings in Swift
Learn how to work with strings in Swift, including string literals, multi-line strings, interpolation, and concatenation, with beginner-friendly examples.
This tutorial belongs to the Swift series
Strings are everywhere in programming: names, messages, file paths, everything a user reads on screen.
In Swift you create a string with the string literal syntax, using double quotes:
let name = "Roger"
Single quotes are not valid string delimiters. 'Roger' doesn’t compile.
Multi-line strings
A string can span multiple lines if you wrap it in three double quotes:
let description = """
a long
long
long description
"""
The indentation of the closing """ decides how much leading whitespace Swift strips from each line. Here every line loses 4 spaces.
Interpolation
To put a value inside a string, use string interpolation: \(...) with an expression inside the parentheses:
let age = 8
let name = """
Roger, age \(age)
Next year he will be \(age + 1)
"""
The result is Roger, age 8 on the first line and Next year he will be 9 on the second. Any expression works inside the parentheses, not just a variable name.
Concatenation
Join two strings with +:
var name = "Roger"
name = name + " The Dog"
Or append with +=:
var name = "Roger"
name += " The Dog"
Or use the append(_:) method:
var name = "Roger"
name.append(" The Dog")
All three leave name equal to "Roger The Dog". Notice name is a var. You can’t append to a let string.
Useful properties and methods
count gives you the number of characters:
let name = "Roger"
name.count // 5
Every string comes with a long list of methods. The ones I use most:
removeFirst()removes the first characterremoveLast()removes the last characterlowercased()returns a new lowercase stringuppercased()returns a new uppercase stringstarts(with:)returnstrueif the string starts with a given substringcontains()returnstrueif the string contains a given character
Indexes and substrings
Here’s the part that surprises people coming from other languages. Strings in Swift are Unicode, and a single character can take a variable amount of memory. So you can’t write name[1] to get the second letter. You have to work with indexes.
Every string gives you its first index through startIndex:
let name = "Roger"
name.startIndex
This is not the number 0. It’s a String.Index value, a position inside that specific string.
To reach a specific position, use index(_:offsetBy:):
let name = "Roger"
let i = name.index(name.startIndex, offsetBy: 2)
name[i] // "g"
The same index gives you a substring:
let name = "Roger"
let i = name.index(name.startIndex, offsetBy: 2)
name.suffix(from: i) // "ger"
// or with the subscript:
name[i...] // "ger"
Be careful: the result is a Substring, not a String:
let name = "Roger"
let i = name.index(name.startIndex, offsetBy: 2)
print(type(of: name.suffix(from: i)))
// Substring
A substring shares memory with the original string instead of copying it, which makes slicing cheap. When you need to keep the result around for a long time, convert it with String(name[i...]) so the original string can be released.
Strings are collections, so you can loop over their characters with for-in. We’ll see that in the loops lessons.
Lesson completed