Swift Case Studies & Practical Application 3 — Questions and Answers
Question 1: You're designing an API for a payment processor. Multiple concrete types (`CreditCard`, `PayPal`, `ApplePay`) must all be usable wherever a `PaymentMethod` is expected. Which Swift mechanism is most appropriate?
- A base class that all types subclass
- A protocol that all types conform to (Correct answer)
- A generic function constrained to Codable
- A typealias grouping the three types
Correct answer: A protocol that all types conform to
A `PaymentMethod` protocol defines the contract (e.g., `charge(amount:)`), and each concrete type independently conforms, enabling polymorphism without inheritance hierarchies.
Question 2: Your app has a `Logger` used across many modules. You want a single shared instance but still allow substituting a mock in tests. Which pattern works best in Swift?
- A global `var logger = Logger()` in a file
- Dependency injection with a `LoggerProtocol` passed into each module (Correct answer)
- A `@Environment` property wrapper everywhere
- A singleton with a `private init` and no protocol
Correct answer: Dependency injection with a `LoggerProtocol` passed into each module
Dependency injection through a protocol lets tests pass a `MockLogger` without changing production code, avoiding the testability trap of a bare singleton.
Question 3: A `Result<[Post], NetworkError>` is returned from a fetch function. You need to map each post's title to uppercase on success. Which approach is most concise?
- `result.map { posts in posts.map { $0.title.uppercased() } }` (Correct answer)
- `if case .success(let posts) = result { posts.map(...) }`
- `try! result.get().map { $0.title.uppercased() }`
- Switch on result and reassign in the success case
Correct answer: `result.map { posts in posts.map { $0.title.uppercased() } }`
`Result.map` transforms the success value without unwrapping, keeping the failure case untouched and producing a new `Result<[String], NetworkError>`.
Question 4: You want SwiftUI's `ProfileView` to automatically re-render when `user.name` changes. `User` is a reference type shared across views. What is the correct setup?
- Conform `User` to `Equatable` only
- Make `User` a class conforming to `ObservableObject` with `@Published var name` (Correct answer)
- Use `@State` with a copy of User in every view
- Add a `willSet` observer on the `user` property
Correct answer: Make `User` a class conforming to `ObservableObject` with `@Published var name`
`ObservableObject` + `@Published` triggers SwiftUI's diffing engine; views holding `@ObservedObject` or `@StateObject` references re-render automatically when `name` changes.
Question 5: A team encounters a crash: `Fatal error: Unexpectedly found nil while unwrapping an Optional value`. You are asked to audit the codebase. Which code pattern most directly causes this crash?
- Using `if let` to unwrap
- Force-unwrapping an optional with `!` when the value is nil (Correct answer)
- Returning an optional from a function
- Using `guard let` with an early return
Correct answer: Force-unwrapping an optional with `!` when the value is nil
The force-unwrap operator `!` crashes at runtime if the optional contains nil; replacing it with `if let`, `guard let`, or `??` eliminates this crash class.
Question 6: You need to sort an array of `Employee` structs by `salary` descending, then by `name` ascending when salaries are equal. Which Swift expression achieves this?
- `employees.sorted { $0.salary > $1.salary }`
- `employees.sorted { $0.salary != $1.salary ? $0.salary > $1.salary : $0.name < $1.name }` (Correct answer)
- `employees.sort(by: \.salary).sort(by: \.name)`
- `employees.sorted(by: [.salary, .name])`
Correct answer: `employees.sorted { $0.salary != $1.salary ? $0.salary > $1.salary : $0.name < $1.name }`
A single comparator closure that checks salary first and falls back to name comparison when salaries are equal implements a stable multi-key sort.
Question 7: An iOS app uploads large files in the background. The upload must continue even if the user leaves the app. Which URLSession configuration is required?
- `URLSession.shared`
- `URLSession(configuration: .background(withIdentifier: "com.app.upload"))` (Correct answer)
- `URLSession(configuration: .ephemeral)`
- `URLSession(configuration: .default)`
Correct answer: `URLSession(configuration: .background(withIdentifier: "com.app.upload"))`
A background URLSession configuration hands off the upload to a system daemon, allowing it to continue after the app is suspended or terminated.
You're designing an API for a payment processor.
Multiple concrete types (`CreditCard`, `PayPal`, `ApplePay`) must all be usable wherever a `PaymentMethod` is expected.
Which Swift mechanism is most appropriate?