Most iOS candidates prep the wrong bucket
iOS loops are not generic coding loops with a Swift skin. They split into DSA, iOS systems, and a UI feature build — and most candidates walk in over-prepared on the wrong bucket. Here is what actually separates staff from senior on the loop, what to study, and what to cut.
iOS onsite loops split into three buckets — DSA, iOS systems, and a UI feature build. Most candidates over-prepare the DSA bucket and get caught flat-footed on the systems round, where , , and navigation architecture separate staff from senior.
Your Swift compiles. Your LeetCode is sharp. You will still fail the iOS loop if you cannot explain why weak var delegate matters without hand-waving.
The real question here is — which bucket is the interviewer actually grading? Most candidates walk in thinking an iOS loop is a generic coding loop with Swift syntax. It is not. The loop is specific, and specificity rewards prep that a generalist LeetCode grinder cannot fake.
What the iOS loop actually looks like
Five rounds of "coding" is a myth. A real iOS onsite splits into three buckets: DSA, iOS systems, and a UI feature build. Every company weights them differently, and the weighting tells you where to spend your prep hours.
| Company | DSA | iOS systems | UI build | Behavioral | System design |
|---|---|---|---|---|---|
| Apple | 2 | 1 | 0–1 | 1 | 0–1 |
| Uber | 1 | 1 | 1 | 1 | 1 |
| Lyft | 1 | 2 | 1 | 1 | 0 |
| Spotify | 1 | 1 | 1 | 1 | 1 |
| 1 | 1 | 1 | 1 | 1 |
Apple is DSA-heavy with iOS platform trivia layered in — memory limits, sandbox rules, why fork() does not exist on iOS. Uber, Spotify, and LinkedIn are balanced: DSA, systems, UI, and a real system design round. On that system design round, your iOS client has to reason about the server side, not hand-wave it. Lyft leans hardest on iOS systems. If you only prepped DSA, Lyft is going to hurt.
The DSA round — do not skip it, do not grind it
The "iOS engineers do not need DSA" myth is wrong. Companies ask LeetCode. The honest version is that the bar is 50 problems deep, not 500 wide. The patterns are the ones iOS engineers solve daily: hash maps for dedup, in-place array ops, LRU cache (same pattern as your image cache), BFS on grids for feeds.
In production, a hash map for dedup saves you from decoding the same 2MB image twice on a scroll. That is not a LeetCode trick. That is Monday morning.
Same failure mode every time. A candidate writes the LRU in fifteen minutes, then cannot defend it against a plain dictionary. If you can write it but not defend it, you are not ready.
Practice hash-map.
Explain your thinking like you're in the interview.
iOS systems — where staff separates from senior
At senior iOS companies, the systems round is no longer trivia. It is whether ownership, actor isolation, , and UI state propagation hold together under shipping pressure.
This is the single highest-leverage section. Three sub-rounds hide inside it.
Memory management
The classic trap: a view controller stores a closure. The closure captures self strongly. A long-lived service holds onto the closure. Your view controller never deallocates. The interviewer shows you the snippet and asks what is wrong.
Most candidates name the . Fewer explain why weak breaks it. Almost none get the unowned case right.
Here is the leak:
// Leaks: closure captures self strongly, service holds it
final class FeedViewModel {
let service: FeedService
init(service: FeedService) {
self.service = service
service.onUpdate = { feed in
self.render(feed) // strong capture leaks
}
}
func render(_ feed: Feed) { /* ... */ }
}And here is the [weak self] fix. This is the one you reach for by default. The VM can outlive or underlive the service, and the closure needs to tolerate both.
final class FeedViewModel {
let service: FeedService
init(service: FeedService) {
self.service = service
service.onUpdate = { [weak self] feed in
guard let self else { return }
self.render(feed)
}
}
func render(_ feed: Feed) { /* ... */ }
}[unowned self] is only safe when the closure cannot outlive self. A child helper owned by the parent qualifies. A service callback does not. Get this wrong in production and you get a crash instead of a leak. That is a worse outcome, not a better one.
The strong answer isn't the clever one — it's the one that names the trade-off.
Concurrency
Swift 6 turned from a best practice into a compiler-enforced design pressure. Apple's own Swift concurrency documentation names the primitives directly: Task, task groups, continuations, , @MainActor, . These are first-class language features — not a GCD replacement you bolt on.
The trap interviewers watch for: candidates who still write GCD code and say "I will migrate when I have to." At Apple and Uber, "when I have to" was last year. An serializes access to its mutable state. A mutex does not give you that contract without discipline. If you cannot name when that difference matters, you cannot ship concurrency at staff level.
Architecture
MVVM. MV. TCA. VIPER. Pick the one you can defend in one sentence.
The iOS 17+ reality: Apple's Observation framework pushes you toward @Observable + SwiftUI. That makes MV viable without a ViewModel layer. Apple frames it as "a robust, type-safe, and performant implementation of the observer design pattern in Swift." That phrasing is not marketing — it is Apple telling you where state propagation is going.
Uber and Lyft codebases still have MVVM inheritance measured in years. Know both patterns, know when each breaks, and know why the interviewer is asking about it. The real question is never "which architecture." It is "which invariant does this architecture protect, and what happens when it leaks."
The UI build — your least-favorite round
Forty-five to sixty minutes, Xcode open, internet off. Build a feed. Build a chat screen. Build a form with validation.
Candidates think this is a SwiftUI-versus-UIKit debate. It is not. The interviewer is watching for state management clarity, not framework choice. Pick the one you are faster in, explain why in fifteen seconds, and ship.
SwiftUI
UIKit
Hiring signal
Modern state flow, declarative thinking
Depth, legacy-codebase experience, performance
State management
@State, @Observable, @Binding
Delegates, view controllers, KVO
When to pick it
Feature build with modern scope
Interviewer explicitly asks, or perf-critical surface
The wrong move
Silent coding with no state reasoning
Writing storyboards from scratch on the whiteboard
The silent candidate fails. The over-talker fails. The narrator who says "I'm reaching for @State here because this view owns its dirty flag" passes.
Company-specific patterns
Five companies, five specific traps. Short version, because this is the part everyone skips to — and the part that matters least on its own.
- Apple — language-agnostic DSA plus platform depth on one topic. They want to see you go deep, not wide. Swift.org's language reference is the authoritative starting point. Read the concurrency chapter cover to cover.
- Uber — Swift concurrency plus ride-matching-as-system-design. Uber's engineering blog has posts on Live Activities and monorepo build speed at scale. The interview expects you to think about cold start, build time, and modularization at the repo level.
- Lyft — balanced, heavy on architecture. Expect an offline-first feature build. Know how you would structure , conflict resolution, and a networking layer that has to work on a subway.
- Spotify — staff scope includes build speed. Release orchestration and developer-experience tooling count as "systems" here, not side quests. Spotify's engineering blog covers XCRemoteCache, XCMetrics, and release pipelines at scale.
- LinkedIn — velocity and stability are one round, not two. LinkedIn's engineering team publicly reports they "release three times a day, with no more than three hours between when code is committed and when that code is available to members." If you cannot reason about preloading, feature flags, and staged rollouts, this round is going to go sideways.
Robinhood, Snap, and Pinterest also hire iOS engineers and run similar loops. Their public primary sources are thinner, so prep off the five above and treat the rest as variations.
The mistakes that kill iOS loops
- Treating the systems round as DSA-in-Swift.
- Showing up without an opinion on SwiftUI versus UIKit.
- Stumbling on
weak varwithout naming the retain cycle and the fix. - No navigation story. Push, present, modal, sheet — when and why.
- Hand-waving concurrency with "I usually use GCD."
- Skipping Swift 6 strict concurrency because "we are not there yet." Apple and Uber already are.
How to prep in four weeks
- Week 1. Fifty DSA problems. Hash map, strings, LRU, BFS on grids. Skip DP. Skip graphs.
- Week 2. Swift language deep dive. Read the Swift concurrency chapter cover to cover. Write three actor examples. Know well enough to argue about it.
- Week 3. Systems plus architecture. Build one toy project in MV with
@Observable. Build one in MVVM. Feel the difference in your hands. - Week 4. Mock builds. Feed. Chat. Form. Out loud. Record yourself. Watch the tape.
The honest close
iOS loops reward opinion. Show up hedging and you fail. Show up with wrong opinions held with confidence and you also fail. The middle path: have an opinion. Know why you hold it. Update it the moment the interviewer names a trade-off you missed.
The iOS loop is not harder than a generic coding loop. It is more specific. Specificity rewards the candidate who prepped the right bucket. It punishes the one who grinded five hundred of the wrong ones.
Practice hash-map.
Explain your thinking like you're in the interview.
Fin and Coco are StrongYes editorial personas from the Council of Ternary Vertices — a trinary-star animal civilization that studies Earth's coding-interview process. Anecdotes map animal-universe experience to human interview mechanics; they are NEVER human-career claims. External citations link to public primary sources.
Grounded in public primary sources: Apple Swift Concurrency documentation, Apple Observation framework docs, Swift.org language reference, Uber Engineering blog (iOS at scale), and the LinkedIn Engineering 3x3 iOS build speed and stability post. No login-walled citations.
Last verified Apr 15, 2026.
Practice Ios.
Reading builds recognition. Explaining builds recall. Run these problems with Fin or Coco.