Skip to main content

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:

swift
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:

swift
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:

swift
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

swift
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:

swift
// 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:

swift
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

swift
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:

swift
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

swift
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

swift
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

swift
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:

  1. String Interpolation: The simplest and most common way to insert values into strings using \(expression) syntax.

  2. Custom String Interpolation: Extend the string interpolation system to provide specialized formatting options.

  3. Format Specifiers: Use String(format:) for more precise control over number formatting and alignment.

  4. NumberFormatter: Format numbers according to localization rules, including currency and decimal styles.

  5. 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

Exercises

  1. Create a function that formats a phone number from digits to the format "(XXX) XXX-XXXX".

  2. Write a custom string interpolation extension that formats file sizes (converting bytes to KB, MB, GB as appropriate).

  3. Create a receipt formatter that takes an array of items with prices and quantities and produces a formatted receipt with a total.

  4. Implement a progress bar formatter that takes a percentage and returns a visual progress bar like [==== ] 40%.

  5. 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! :)