Swift Foundation
Essential framework for dates, files, networking, and more
🏗️ What is Swift Foundation?
Foundation is Apple's fundamental framework providing essential data types, collections, and operating-system services. It includes dates, URLs, file management, networking, and data formatting - the building blocks for most Swift applications.
import Foundation
// Foundation provides essential types
let now = Date()
let url = URL(string: "https://example.com")
let data = "Hello".data(using: .utf8)
let uuid = UUID()
print("Current time: \(now)")
print("UUID: \(uuid.uuidString)")
Key Foundation Components
Date & Time
Working with dates and time
let now = Date()
let formatter = DateFormatter()
formatter.dateStyle = .medium
URLs & Networking
URL handling and network requests
let url = URL(string: "https://api.example.com")
let task = URLSession.shared.dataTask(with: url!)
File Management
Reading and writing files
let fileManager = FileManager.default
let documentsPath = fileManager.urls(for: .documentDirectory)
Data & Encoding
Data manipulation and JSON
let jsonData = try JSONEncoder().encode(object)
let decoded = try JSONDecoder().decode(Type.self, from: data)
🔹 Working with Dates
Foundation provides powerful date and time handling:
import Foundation
// Creating dates
let now = Date()
let specificDate = Date(timeIntervalSince1970: 1640995200) // Jan 1, 2022
// Date formatting
let formatter = DateFormatter()
formatter.dateStyle = .full
formatter.timeStyle = .short
let formatted = formatter.string(from: now)
// Custom date format
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let customFormatted = formatter.string(from: now)
// Date components
let calendar = Calendar.current
let components = calendar.dateComponents([.year, .month, .day], from: now)
let year = components.year
let month = components.month
let day = components.day
// Date calculations
let tomorrow = calendar.date(byAdding: .day, value: 1, to: now)
let nextWeek = calendar.date(byAdding: .weekOfYear, value: 1, to: now)
// Comparing dates
let isToday = calendar.isDateInToday(now)
let isSameDay = calendar.isDate(now, inSameDayAs: specificDate)
print("Today: \(formatted)")
print("Year: \(year ?? 0), Month: \(month ?? 0), Day: \(day ?? 0)")
🔹 URL and Networking
Handle URLs and make network requests:
import Foundation
// Creating URLs
let urlString = "https://jsonplaceholder.typicode.com/posts/1"
guard let url = URL(string: urlString) else {
print("Invalid URL")
return
}
// URL components
let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
print("Host: \(components?.host ?? "Unknown")")
print("Path: \(components?.path ?? "Unknown")")
// Simple GET request
func fetchData() async {
do {
let (data, response) = try await URLSession.shared.data(from: url)
if let httpResponse = response as? HTTPURLResponse {
print("Status code: \(httpResponse.statusCode)")
}
if let jsonString = String(data: data, encoding: .utf8) {
print("Response: \(jsonString)")
}
} catch {
print("Error: \(error)")
}
}
// POST request with JSON
func postData() async {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let postData = ["title": "New Post", "body": "Post content"]
do {
let jsonData = try JSONSerialization.data(withJSONObject: postData)
request.httpBody = jsonData
let (data, _) = try await URLSession.shared.data(for: request)
print("Posted successfully")
} catch {
print("Error posting: \(error)")
}
}
🔹 File Management
Read, write, and manage files on the device:
import Foundation
let fileManager = FileManager.default
// Get common directories
let documentsURL = fileManager.urls(for: .documentDirectory,
in: .userDomainMask).first!
let desktopURL = fileManager.urls(for: .desktopDirectory,
in: .userDomainMask).first!
// Create file path
let fileName = "myfile.txt"
let fileURL = documentsURL.appendingPathComponent(fileName)
// Write to file
let content = "Hello, Foundation!"
do {
try content.write(to: fileURL, atomically: true, encoding: .utf8)
print("File written successfully")
} catch {
print("Error writing file: \(error)")
}
// Read from file
do {
let readContent = try String(contentsOf: fileURL, encoding: .utf8)
print("File content: \(readContent)")
} catch {
print("Error reading file: \(error)")
}
// Check if file exists
let fileExists = fileManager.fileExists(atPath: fileURL.path)
print("File exists: \(fileExists)")
// Get file attributes
do {
let attributes = try fileManager.attributesOfItem(atPath: fileURL.path)
let fileSize = attributes[.size] as? Int64
let modificationDate = attributes[.modificationDate] as? Date
print("File size: \(fileSize ?? 0) bytes")
print("Modified: \(modificationDate ?? Date())")
} catch {
print("Error getting attributes: \(error)")
}
// Delete file
do {
try fileManager.removeItem(at: fileURL)
print("File deleted")
} catch {
print("Error deleting file: \(error)")
}
🔹 JSON and Data Encoding
Work with JSON and data serialization:
import Foundation
// Define a Codable struct
struct Person: Codable {
let name: String
let age: Int
let email: String
}
struct Company: Codable {
let name: String
let employees: [Person]
let founded: Date
}
// Create sample data
let employees = [
Person(name: "Alice", age: 30, email: "[email protected]"),
Person(name: "Bob", age: 25, email: "[email protected]")
]
let company = Company(name: "Tech Corp",
employees: employees,
founded: Date())
// Encode to JSON
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
encoder.outputFormatting = .prettyPrinted
do {
let jsonData = try encoder.encode(company)
let jsonString = String(data: jsonData, encoding: .utf8)
print("JSON:\n\(jsonString ?? "Error")")
// Decode from JSON
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let decodedCompany = try decoder.decode(Company.self, from: jsonData)
print("\nDecoded company: \(decodedCompany.name)")
print("Employees: \(decodedCompany.employees.count)")
} catch {
print("Encoding/Decoding error: \(error)")
}
// Working with raw JSON
let jsonString = """
{
"name": "John",
"age": 35,
"active": true
}
"""
if let jsonData = jsonString.data(using: .utf8) {
do {
let json = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any]
let name = json?["name"] as? String
let age = json?["age"] as? Int
print("Name: \(name ?? "Unknown")")
print("Age: \(age ?? 0)")
} catch {
print("JSON parsing error: \(error)")
}
}
🔹 UserDefaults and Preferences
Store user preferences and simple data:
import Foundation
let defaults = UserDefaults.standard
// Storing different types
defaults.set("John Doe", forKey: "username")
defaults.set(25, forKey: "userAge")
defaults.set(true, forKey: "isFirstLaunch")
defaults.set(Date(), forKey: "lastLoginDate")
// Storing arrays and dictionaries
let favoriteColors = ["red", "blue", "green"]
defaults.set(favoriteColors, forKey: "favoriteColors")
let userInfo = ["name": "Alice", "role": "admin"]
defaults.set(userInfo, forKey: "userInfo")
// Reading values
let username = defaults.string(forKey: "username") ?? "Unknown"
let userAge = defaults.integer(forKey: "userAge")
let isFirstLaunch = defaults.bool(forKey: "isFirstLaunch")
let lastLogin = defaults.object(forKey: "lastLoginDate") as? Date
// Reading arrays and dictionaries
let colors = defaults.array(forKey: "favoriteColors") as? [String] ?? []
let info = defaults.dictionary(forKey: "userInfo") ?? [:]
print("Username: \(username)")
print("Age: \(userAge)")
print("First launch: \(isFirstLaunch)")
print("Favorite colors: \(colors)")
// Removing values
defaults.removeObject(forKey: "isFirstLaunch")
// Check if key exists
let hasUsername = defaults.object(forKey: "username") != nil
// Synchronize (usually not needed)
defaults.synchronize()
🔹 Foundation Best Practices
Guidelines for effective Foundation usage:
✅ Do:
- Use Codable for JSON serialization when possible
- Handle errors properly when working with files and network
- Use async/await for network requests
- Cache expensive operations like date formatting
- Use UserDefaults for simple preferences only
❌ Don't:
- Store large data in UserDefaults
- Block the main thread with file operations
- Ignore URL validation when creating URLs
- Use force unwrapping with file operations