Swift String Formatting
When building applications, you'll often need to create strings that combine fixed text with dynamic values. Swift provides several powerful methods for formatting strings to display information in a clear, consistent, and localized manner. In this guide, we'll explore various string formatting techniques available in Swift.
Introduction to String Formatting
String formatting refers to the process of constructing strings by combining static text with dynamic values, often with specific formatting requirements. Swift offers multiple approaches to string formatting, from simple string interpolation to more advanced formatting options for numbers, dates, and custom types.
Proper string formatting is essential for:
- Creating readable user interface text
- Generating consistent output for logging
- Formatting numbers and dates according to locale conventions
- Building complex strings with dynamic content
Let's explore the various techniques available in Swift.
String Interpolation
The most common way to format strings in Swift is through string interpolation, which allows you to embed expressions directly within string literals.
Basic String Interpolation
String interpolation uses the \(expression)
syntax to insert values into strings:
let name = "Taylor"
let age = 29
let greeting = "Hello, my name is \(name) and I'm \(age) years old."
print(greeting)
// Output: Hello, my name is Taylor and I'm 29 years old.
You can place any valid Swift expression inside the parentheses:
let a = 5
let b = 10
print("The sum of \(a) and \(b) is \(a + b)")
// Output: The sum of 5 and 10 is 15
Custom String Interpolation (Swift 5+)
Swift 5 introduced extended string interpolation, allowing you to define custom ways to interpolate values:
extension String.StringInterpolation {
mutating func appendInterpolation(decimal value: Double, precision: Int) {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = precision
formatter.maximumFractionDigits = precision
if let result = formatter.string(from: NSNumber(value: value)) {
appendLiteral(result)
}
}
}
let pi = 3.14159
print("Pi to 2 decimal places is \(decimal: pi, precision: 2)")
// Output: Pi to 2 decimal places is 3.14
String Format Specifiers
Swift inherited the ability to use format specifiers from Objective-C through the String(format:)
initializer.
Basic Format Specifiers
let name = "Swift"
let version = 5.5
let year = 2014
let info = String(format: "%@ was initially released in %d and is now at version %.1f", name, year, version)
print(info)
// Output: Swift was initially released in 2014 and is now at version 5.5
Common format specifiers include:
%@
: Object (String, etc.)%d
: Integer%f
: Float/Double%.2f
: Float/Double with 2 decimal places%x
: Hexadecimal%%
: Literal percentage sign
Width and Alignment
You can control the width and alignment of formatted values:
// Right-aligned with padding
let rightAligned = String(format: "%10d", 42)
print("|\(rightAligned)|")
// Output: | 42|
// Left-aligned with padding
let leftAligned = String(format: "%-10d", 42)
print("|\(leftAligned)|")
// Output: |42 |
// Zero-padding for numbers
let zeroPadded = String(format: "%05d", 42)
print(zeroPadded)
// Output: 00042
Number Formatting with NumberFormatter
For more advanced number formatting, Swift provides the NumberFormatter
class:
let number = 1234567.89
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.groupingSeparator = ","
formatter.decimalSeparator = "."
if let formattedNumber = formatter.string(from: NSNumber(value: number)) {
print("Formatted number: \(formattedNumber)")
// Output: Formatted number: 1,234,567.89
}
Currency Formatting
let price = 29.99
let currencyFormatter = NumberFormatter()
currencyFormatter.numberStyle = .currency
currencyFormatter.locale = Locale(identifier: "en_US")
if let formattedPrice = currencyFormatter.string(from: NSNumber(value: price)) {
print("The item costs \(formattedPrice)")
// Output: The item costs $29.99
}
// Change locale for different currency format
currencyFormatter.locale = Locale(identifier: "fr_FR")
if let formattedPriceEuro = currencyFormatter.string(from: NSNumber(value: price)) {
print("In Europe, the item costs \(formattedPriceEuro)")
// Output: In Europe, the item costs 29,99 €
}
Date Formatting with DateFormatter
Formatting dates is a common requirement in many applications:
let now = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .short
let formattedDate = dateFormatter.string(from: now)
print("Current date and time: \(formattedDate)")
// Output: Current date and time: August 15, 2023 at 3:30 PM
Custom Date Patterns
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
let formattedDate = dateFormatter.string(from: Date())
print("ISO-style date: \(formattedDate)")
// Output: ISO-style date: 2023-08-15 15:30
Practical Examples
User Profile Display
struct User {
let name: String
let age: Int
let joinDate: Date
let premiumMember: Bool
}
func formatUserProfile(_ user: User) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
let memberStatus = user.premiumMember ? "Premium" : "Standard"
return """
User Profile:
Name: \(user.name)
Age: \(user.age)
Joined: \(dateFormatter.string(from: user.joinDate))
Status: \(memberStatus)
"""
}
let user = User(
name: "John Doe",
age: 32,
joinDate: Date(timeIntervalSince1970: 1577836800), // Jan 1, 2020
premiumMember: true
)
print(formatUserProfile(user))
// Output:
// User Profile:
// Name: John Doe
// Age: 32
// Joined: Jan 1, 2020
// Status: Premium
Table Formatting
func formatTable(headers: [String], data: [[String]]) -> String {
// Calculate column widths
var columnWidths = headers.map { $0.count }
for row in data {
for (i, item) in row.enumerated() {
if i < columnWidths.count {
columnWidths[i] = max(columnWidths[i], item.count)
}
}
}
// Format headers
var result = ""
for (i, header) in headers.enumerated() {
let format = "%-\(columnWidths[i] + 2)s"
result += String(format: format, header)
}
result += "\n"
// Add separator line
for width in columnWidths {
result += String(repeating: "-", count: width + 2)
}
result += "\n"
// Format data rows
for row in data {
for (i, item) in row.enumerated() {
if i < columnWidths.count {
let format = "%-\(columnWidths[i] + 2)s"
result += String(format: format, item)
}
}
result += "\n"
}
return result
}
let headers = ["Product", "Price", "Quantity"]
let data = [
["iPhone", "$999", "5"],
["MacBook Pro", "$1999", "2"],
["AirPods", "$199", "10"]
]
print(formatTable(headers: headers, data: data))
// Output:
// Product Price Quantity
// --------- ------- ---------
// iPhone $999 5
// MacBook Pro $1999 2
// AirPods $199 10
Summary
String formatting in Swift provides several powerful approaches:
-
String Interpolation: The simplest and most common way to insert values into strings using
\(expression)
syntax. -
Custom String Interpolation: Extend the string interpolation system to provide specialized formatting options.
-
Format Specifiers: Use
String(format:)
for more precise control over number formatting and alignment. -
NumberFormatter: Format numbers according to localization rules, including currency and decimal styles.
-
DateFormatter: Format dates and times with built-in or custom patterns.
By mastering these string formatting techniques, you can ensure your Swift applications display information in a clear, consistent, and user-friendly manner.
Further Resources and Exercises
Resources
- Apple's String Programming Guide
- Swift Documentation on String Interpolation
- NumberFormatter Documentation
Exercises
-
Create a function that formats a phone number from digits to the format "(XXX) XXX-XXXX".
-
Write a custom string interpolation extension that formats file sizes (converting bytes to KB, MB, GB as appropriate).
-
Create a receipt formatter that takes an array of items with prices and quantities and produces a formatted receipt with a total.
-
Implement a progress bar formatter that takes a percentage and returns a visual progress bar like
[==== ] 40%
. -
Create a formatter for time durations that converts seconds into a human-readable format (e.g., "2 hours, 30 minutes").
By practicing these exercises, you'll develop a strong understanding of string formatting in Swift and how to apply it in real-world situations.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)