Chapter 66: Swift Dictionaries
1. What is a Dictionary in Swift? (the most important intuition)
A dictionary is a collection that stores key → value pairs.
You ask: “Give me the value associated with this key.”
It’s like:
- a real-life dictionary (word → meaning)
- a phone book (name → phone number)
- user settings (setting name → value)
- JSON data (field name → value)
- a configuration object
- a lookup table
The most important property of a dictionary:
You can very quickly find a value if you know its key (usually O(1) time — extremely fast, even with millions of items)
2. Basic syntax — the most common ways to create dictionaries
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// Most readable way — literal syntax let profile: [String: Any] = [ "name": "Rahul Verma", "age": 27, "city": "Bengaluru", "isPremium": true, "points": 14520, "lastLogin": Date() ] // Empty dictionary var settings: [String: Bool] = [:] var scores = [String: Int]() // same thing // From arrays (very common when converting data) let keys = ["theme", "fontSize", "notifications"] let values = ["dark", 16, true] let combined = Dictionary(uniqueKeysWithValues: zip(keys, values)) |
3. Reading, writing, updating, removing — the core operations
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
var user: [String: Any] = [ "name": "Priya Reddy", "age": 24, "city": "Hyderabad" ] // Read (returns Optional!) if let name = user["name"] as? String { print("Name: \(name)") } // Safe read with default (very common pattern) let city = user["city"] as? String ?? "Unknown" print("City: \(city)") // Update existing key user["age"] = 25 // Add new key-value user["isPremium"] = true user["favoriteColor"] = "Blue" // Remove key user["age"] = nil // removes "age" // Check if key exists if user["isPremium"] != nil { print("User has premium status") } // Count & empty check print(user.count) // e.g. 4 print(user.isEmpty) // false |
4. Real-life examples — dictionaries you will actually use
Example 1 — User profile / settings (extremely common)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
var userProfile: [String: Any] = [ "fullName": "Aarav Sharma", "email": "aarav@example.com", "age": 19, "countryCode": "IN", "darkMode": true, "fontScale": 1.1, "notificationSound": "chime", "lastActive": Date() ] // Reading safely let name = userProfile["fullName"] as? String ?? "Guest" let darkModeEnabled = userProfile["darkMode"] as? Bool ?? false // Updating from server response userProfile["points"] = 14520 userProfile["lastActive"] = Date() // Print all settings print("User profile:") for (key, value) in userProfile { print(" \(key): \(value)") } |
Example 2 — Settings / preferences screen
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
var appSettings: [String: Any] = [ "theme": "system", "fontSize": 16, "autoPlayVideos": true, "language": "en-IN", "locationEnabled": false ] // Apply settings if let theme = appSettings["theme"] as? String { switch theme { case "dark": applyDarkTheme() case "light": applyLightTheme() default: applySystemTheme() } } if let fontSize = appSettings["fontSize"] as? CGFloat { setAppFontSize(fontSize) } |
Example 3 — JSON-like data / API response (very frequent)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
let apiResponse: [String: Any] = [ "status": "success", "user": [ "id": 12345, "name": "Sneha", "email": "sneha@example.com", "isPremium": true, "preferences": [ "theme": "dark", "language": "en" ] ], "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ] // Safe nested access (classic pattern) if let status = apiResponse["status"] as? String, status == "success", let userDict = apiResponse["user"] as? [String: Any], let userName = userDict["name"] as? String { print("Welcome, \(userName)!") } |
5. Strongly typed dictionaries — modern & recommended style
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
enum UserKey: String, Hashable { case name case age case email case isPremium case joinDate } var typedProfile: [UserKey: Any] = [ .name: "Rahul Verma", .age: 27, .email: "rahul@example.com", .isPremium: true ] // Access if let name = typedProfile[.name] as? String { print("Hello, \(name)") } |
Why this is better:
- No magic strings → typos are caught at compile time
- Auto-complete works
- Refactoring is safe
6. Very Common Beginner Mistakes & Correct Habits
| Mistake | Wrong / Dangerous code | Correct / Better habit | Why? |
|---|---|---|---|
| Force-unwrapping dictionary values | let name = dict[“name”] as! String | let name = dict[“name”] as? String ?? “Guest” | Missing key → crash |
| Using Any everywhere | [String: Any] for everything | Use concrete types or enum keys when possible | Less safety, harder debugging |
| Assuming order in Dictionary | for (k,v) in dict { print(k) } | Never rely on order — use Array if order matters | Dictionaries are unordered (or insertion order only) |
| Modifying while iterating | for (k,v) in dict { dict[k] = … } | Collect changes in new dict or use for key in dict.keys | Runtime error: collection mutated |
| Checking existence incorrectly | if dict[“key”] != nil { … } | if dict.keys.contains(“key”) { … } or if let _ = dict[“key”] { … } | More explicit |
7. Quick Reference — Dictionary operations you will use every day
| Goal | Code example | Returns / modifies original? |
|---|---|---|
| Read value safely | dict[“key”] as? String ?? “default” | — |
| Update / add value | dict[“key”] = newValue | modifies original |
| Remove key | dict[“key”] = nil | modifies original |
| Check if key exists | dict.keys.contains(“key”) or if let _ = dict[“key”] | Bool |
| Loop over all pairs | for (key, value) in dict { … } | — |
| Get all keys / values | Array(dict.keys) / Array(dict.values) | new arrays |
| Merge two dictionaries | dict1.merge(dict2) { $1 } | modifies dict1 |
8. Small Practice — Try these
- Create a dictionary for a user profile keys: name, age, city, isPremium, points → Print all key-value pairs → Change age to 25 → Add “favoriteColor”: “Blue”
- Create a settings dictionary keys: theme (“dark”/”light”), fontSize (16), notificationsEnabled (true) → Apply theme based on value → Print current font size
- Create dictionary from two arrays keys = [“name”, “score”, “rank”] values = [“Rahul”, 920, 5] → Print the resulting dictionary
Paste your code here if you want feedback or want to see more polished versions!
What would you like to explore next?
- Dictionary with typed keys (enum-based — very modern & safe)
- Default values & merging dictionaries
- Nested dictionaries (JSON-like structures)
- Sets in depth (uniqueness, fast lookup)
- Array vs Set vs Dictionary decision guide
- Collections in SwiftUI (List, ForEach, @State)
Just tell me — we’ll continue in the same clear, detailed, patient style 😊
