Chapter 29: Swift Strings
1. What is a String in Swift?
A String is a sequence of characters — basically, text.
In Swift:
- A String can contain letters, numbers, symbols, emoji, Unicode characters from any language (Hindi, Telugu, Arabic, Chinese, Japanese, etc.)
- Strings are value types → when you assign or pass them, a copy is made
- Strings are immutable when declared with let (you cannot change the content)
- Strings are mutable when declared with var (you can change, append, replace)
|
0 1 2 3 4 5 6 7 |
let greeting = "Namaste, Hyderabad! 🌶️" // immutable – cannot change var message = "Hello" // mutable – can be changed |
2. Creating Strings – all the common ways
|
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 |
// Simple string literal let name = "Aarav" // Empty string let empty = "" let alsoEmpty = String() // same thing // Multi-line string (very clean & common) let poem = """ Roses are red, Violets are blue, Swift is awesome, And so are you! 😊 """ // String interpolation – the #1 way you will build strings let age = 19 let city = "Hyderabad" let intro = "My name is \(name), I am \(age) years old and live in \(city)." // Raw string – ignores escapes (very useful for regex, paths, JSON) let regex = #"\d{3}-\d{3}-\d{4}"# let windowsPath = #"C:\Users\Public\Documents"# let jsonLike = #"{ "name": "Priya" }"# |
3. Most Useful String Properties & Methods (you use these every day)
|
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 text = "Swift is beautiful and powerful! 😊" // Length print(text.count) // 34 (counts characters, not bytes) // Empty check print(text.isEmpty) // false // Case conversion print(text.uppercased()) // SWIFT IS BEAUTIFUL AND POWERFUL! 😊 print(text.lowercased()) // swift is beautiful and powerful! 😊 // Check prefix / suffix print(text.hasPrefix("Swift")) // true print(text.hasSuffix("😊")) // true // Contains print(text.contains("beautiful")) // true print(text.contains("ugly")) // false // Replace let cleaned = text.replacingOccurrences(of: "powerful", with: "amazing") print(cleaned) // Swift is beautiful and amazing! 😊 |
4. Looping over characters (very common pattern)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
let word = "नमस्ते" for character in word { print(character) } // Output: // न // म // स // ् // त // े |
Important: Swift loops over grapheme clusters (human-visible characters), not Unicode scalars or bytes.
That’s why “😊”.count == 1 and “नमस्ते”.count == 6 (even though it looks like 6 characters).
5. String Interpolation – the modern way to build text
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
let product = "iPhone 16" let price = 119900 let rating = 4.85 let message = """ Product: \(product) Price: ₹\(price) Rating: \(rating) stars """ print(message) |
Advanced interpolation (very clean 2024–2026 style)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
let temperature = 36.7 let status = temperature > 38 ? "Fever" : "Normal" let healthReport = """ Temperature: \(temperature, format: .number.precision(.fractionLength(1)))°C Status: \(status) """ print(healthReport) |
6. Working with substrings & indices (important but tricky)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
let fullName = "Sneha Reddy" // First character let first = fullName[fullName.startIndex] // "S" // Last character let last = fullName[fullName.index(before: fullName.endIndex)] // "y" // Substring (5 characters from start) let firstFive = fullName.prefix(5) // "Sneha" // From index 6 to end let lastName = fullName.dropFirst(6) // "Reddy" // Using range let range = fullName.index(fullName.startIndex, offsetBy: 6)... let surname = fullName[range] // "Reddy" |
Modern & safer way (most common 2025 style)
|
0 1 2 3 4 5 6 7 8 9 |
if let spaceIndex = fullName.firstIndex(of: " ") { let firstName = fullName[..<spaceIndex] // "Sneha" let lastNamePart = fullName[fullName.index(after: spaceIndex)...] // "Reddy" } |
7. Very Common Real-Life Examples
Example 1 – Username validation
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
func isValidUsername(_ username: String) -> Bool { let trimmed = username.trimmingCharacters(in: .whitespacesAndNewlines) return !trimmed.isEmpty && trimmed.count >= 3 && trimmed.count <= 20 && trimmed.allSatisfy { $0.isLetter || $0.isNumber || $0 == "_" || $0 == "." } } print(isValidUsername("aarav_007")) // true print(isValidUsername(" a ")) // false |
Example 2 – Phone number formatting (very common)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
func formatIndianPhone(_ number: String) -> String { let digits = number.filter { $0.isNumber } guard digits.count == 10 else { return number } let prefix = "+91 " let part1 = digits.prefix(5) let part2 = digits.dropFirst(5) return prefix + part1 + " " + part2 } print(formatIndianPhone("9876543210")) // +91 98765 43210 |
Example 3 – Password strength meter
|
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 |
func passwordStrength(_ password: String) -> String { let lengthScore = password.count >= 12 ? 3 : password.count >= 8 ? 2 : 1 let hasUpper = password.range(of: "[A-Z]", options: .regularExpression) != nil let hasLower = password.range(of: "[a-z]", options: .regularExpression) != nil let hasDigit = password.range(of: "[0-9]", options: .regularExpression) != nil let hasSpecial = password.range(of: "[!@#$%^&*]", options: .regularExpression) != nil let varietyScore = [hasUpper, hasLower, hasDigit, hasSpecial].filter { $0 }.count let total = lengthScore + varietyScore switch total { case 6...7: return "Very Strong 💪" case 4...5: return "Strong 👍" case 2...3: return "Medium 😐" default: return "Weak 😟" } } print(passwordStrength("Passw0rd!")) // Strong 👍 |
8. Quick Summary – Most Used String Operations
| Goal | Best code example | Notes |
|---|---|---|
| Build message with values | “Hi \(name), age: \(age)” | String interpolation – #1 method |
| Multi-line text | “”” … “”” | Clean & readable |
| Length | text.count | Counts characters (emoji = 1) |
| Check empty | text.isEmpty or text == “” | — |
| Upper / lower | text.uppercased(), text.lowercased() | For case-insensitive comparison |
| Contains | text.contains(“word”) | Simple substring check |
| Replace | text.replacingOccurrences(of: “old”, with: “new”) | Immutable – returns new string |
| Trim whitespace | text.trimmingCharacters(in: .whitespacesAndNewlines) | Removes leading/trailing spaces |
| Loop over characters | for char in text { … } | Each char is a Character |
9. Small Practice – Try these
- Create a greeting message with name, age, city using interpolation
- Check if a string contains both “@” and “.” (simple email check)
- Format a 10-digit phone number as +91 XXXXX XXXXX
Paste your attempts if you want feedback!
What would you like to explore more deeply next?
- Advanced string manipulation (regular expressions, splitting, joining)
- String performance & mutability (String vs NSMutableString)
- Unicode & emoji handling in detail
- Strings in SwiftUI (Text, labels, formatting)
- Or move to another topic (arrays, dictionaries, optionals, functions…)
Just tell me — we’ll continue in the same clear, detailed, teacher-like way 😊
