iOS interview questions in 2026 focus on four areas: Swift language fundamentals, memory management with ARC, Swift concurrency (async/await, actors, Sendable), and SwiftUI state management, with UIKit still expected as a fallback. Mid-level and senior loops add an architecture discussion and a mobile system design round, usually an offline-first feed or chat app. The best preparation is to practice explaining trade-offs out loud, not memorizing definitions.
This guide covers each area with the questions interviewers actually ask, short model answers, and a worked offline-first feed design you can reuse in your own system design round.
Key Takeaways
- Concurrency is the new filter. Since Swift 6 added a language mode that checks data races at compile time, questions on actors,
Sendable, and@MainActorhave replaced most GCD trivia. - SwiftUI questions are about data flow, not modifiers. Know
@State,@Binding,@Observable,@Environment, and how view identity affects state. - ARC still shows up in every loop. Be ready to spot a retain cycle in a closure and explain
weakversusunownedwithout hesitation. - Architecture answers should name trade-offs. MVVM is the safe default; TCA is a valid answer if you can explain why its cost is worth it.
- Mobile system design is its own skill. Offline support, pagination, image caching, and sync conflicts matter more than server sharding.
What Does the iOS Developer Interview Loop Look Like?
An iOS developer interview usually runs four to six rounds after a recruiter call. The exact mix depends on company size, but the building blocks are consistent.
| Round | What it tests | Typical length | Common at |
|---|---|---|---|
| Recruiter screen | Background, level, motivation | 30 min | Everyone |
| Technical phone screen | Swift fundamentals or one coding problem | 45-60 min | Everyone |
| Algorithms coding | Data structures in Swift | 45-60 min | Big tech |
| Practical iOS coding | Build or fix a screen, networking, state | 60-90 min | Startups, mid-size |
| Take-home | Small app with tests | 3-6 hours | Startups |
| Mobile system design | App architecture, offline, sync | 45-60 min | Mid-level and above |
| Behavioral | Ownership, collaboration, conflict | 45 min | Everyone |
At big tech, the algorithms round is often shared with backend candidates, so practice common coding interview patterns in Swift rather than Python. If you are targeting Apple specifically, the loop is team-driven and varies a lot; the Apple technical interview process guide breaks down what to expect there.
Swift Language Fundamentals
Swift fundamentals questions test whether you understand the type system well enough to make design choices, not whether you can recite keywords. These come up in almost every phone screen.
What is the difference between a struct and a class? A struct is a value type: assignment copies it, and each copy is independent. A class is a reference type: assignment shares one instance, it supports inheritance, and its lifetime is managed by ARC. Prefer structs for models and state; reach for classes when you need identity, shared mutable state, or Objective-C interop.
What is copy-on-write? Copy-on-write is an optimization where a value type shares its storage until one copy is mutated, and only then makes a real copy. Swift's Array, Dictionary, and String use it, so passing large collections around is cheap. You can implement it for your own types with isKnownUniquelyReferenced.
How do optionals work? An optional is an enum with two cases, .some(Wrapped) and .none. Interviewers want to hear you prefer if let, guard let, and optional chaining over force unwrapping, and that you can explain when a crash on ! is actually the right call (a programmer error that should never happen).
Other fundamentals worth rehearsing:
- Protocols with associated types and why
some View(opaque type) differs fromany Shape(existential). - Generics with constraints, such as
func merge<T: Hashable>(_ a: [T], _ b: [T]) -> [T]. - Enums with associated values for modeling state, such as
enum LoadState { case idle, loading, loaded([Post]), failed(Error) }. - Error handling with
throws, typed throws (added in Swift 6), andResult. - Property wrappers and macros, since
@Observableand#Previeware both macros.
Memory Management and ARC
ARC (Automatic Reference Counting) is Swift's memory model: the compiler inserts retain and release calls, and an object is freed when its strong reference count reaches zero. ARC does not collect cycles, which is why retain cycle questions never go away.
The classic question shows a closure that captures self:
final class FeedViewModel {
var onUpdate: (() -> Void)?
private var posts: [Post] = []
func bind() {
onUpdate = {
print(self.posts.count)
}
}
}
The view model owns the closure and the closure strongly captures the view model, so neither is ever freed. The fix is a capture list:
onUpdate = { [weak self] in
guard let self else { return }
print(self.posts.count)
}
When should you use unowned instead of weak? Use weak when the referenced object can be deallocated first; it becomes an optional and goes to nil safely. Use unowned only when you can guarantee the referenced object outlives the reference, such as a child that cannot exist without its parent. Accessing a deallocated unowned reference crashes.
Follow-up questions to expect:
- Why delegates are declared
weak var delegate: SomeDelegate?and why the protocol needs to be class-constrained (AnyObject). - Whether a
Task { }inside a class capturesselfstrongly (it does, for the lifetime of the task), and how to cancel long-running tasks indeinitor with SwiftUI's.taskmodifier. - How you find leaks in practice: Xcode's Memory Graph Debugger and the Leaks instrument.
Swift Concurrency Interview Questions: async/await, Actors, and Sendable
Swift concurrency is the area where the interview bar moved most. Swift 6 introduced a language mode that turns data races into compile-time errors, and Swift 6.2 followed with "approachable concurrency" settings, including an option to make code default to main-actor isolation. Interviewers now expect you to reason about isolation, not just call DispatchQueue.main.async.
What does async/await replace? It replaces nested completion handlers with linear code that can suspend. An await marks a possible suspension point where the thread is freed for other work. Errors propagate with try instead of being passed through callbacks.
What is structured concurrency? Structured concurrency means child tasks are bound to the scope that created them: they finish or are cancelled before the parent returns. async let and withTaskGroup are structured; Task { } and Task.detached { } are unstructured.
func loadProfile(id: User.ID) async throws -> ProfileScreen {
async let user = api.user(id)
async let posts = api.posts(for: id, limit: 20)
return try await ProfileScreen(user: user, posts: posts)
}
Both requests run in parallel, and if one throws, the other is cancelled automatically.
What is an actor? An actor is a reference type that serializes access to its mutable state. Outside callers must await its methods, which is how the compiler proves there is no data race.
actor ImageCache {
private var store: [URL: Data] = [:]
func data(for url: URL) -> Data? { store[url] }
func insert(_ data: Data, for url: URL) { store[url] = data }
}
What is actor reentrancy? While an actor method is suspended at an await, other calls can run on the same actor. State you read before the await may be stale after it. Strong candidates mention the fix: re-check state after suspension, or store in-flight Task values in a dictionary so duplicate requests share one download.
What does Sendable mean? A Sendable type is safe to pass across concurrency domains. Value types with Sendable members qualify automatically; classes need to be final with immutable stored properties, or use internal synchronization and be marked @unchecked Sendable, which you should be ready to justify.
What is @MainActor? It is a global actor that runs code on the main thread. Mark view models and UI-facing types with it so property updates that drive the UI are always on the main thread. For deeper threading questions that go beyond Swift, see these concurrency and multithreading interview questions.
Concurrency questions are where many candidates freeze, because the answer depends on reasoning through isolation in real time while someone watches.
Stuck on an actor reentrancy follow-up mid-interview? TechScreen gives you real-time hints on Swift concurrency and SwiftUI questions, invisible during screen share on Zoom, Meet, and Teams. Start with 3 free tokens, no credit card.
SwiftUI vs UIKit: What Interviewers Want to Hear
SwiftUI is Apple's declarative UI framework: you describe UI as a function of state, and the framework updates the view hierarchy when state changes. UIKit is the imperative framework that preceded it. In 2026, the right answer is "SwiftUI by default, UIKit where it earns its place."
| Question | SwiftUI | UIKit |
|---|---|---|
| Default for new screens | Yes | Rarely |
| Very large, highly custom lists | Improving, profile first | UICollectionView with diffable data source |
| Fine-grained control of transitions and gestures | Good, sometimes limited | Full control |
| Minimum OS constraints | Newer APIs need newer iOS | Works everywhere |
| Interop | UIViewRepresentable, UIViewControllerRepresentable | UIHostingController |
SwiftUI interview questions to rehearse:
@Statevs@Bindingvs@Observable.@Stateowns local value state for one view.@Bindingis a two-way reference to state owned elsewhere.@Observable(iOS 17+) marks a model class whose properties SwiftUI tracks per property, replacing mostObservableObjectand@Publishedusage.- Why does my view's state reset? Because view identity changed. Conditional branches, changing
.id()values, and unstableForEachidentifiers create new views with fresh state. - Where do side effects go? In
.taskfor async work tied to view lifetime (it cancels automatically on disappear), and.onChange(of:)for reactions to state changes. - Why is my list slow? Expensive
bodycomputations, non-stable IDs, or a model that triggers updates for too many views. Mention Instruments' SwiftUI tooling andSelf._printChanges()for debugging.
Apple's SwiftUI documentation is the reference to cite when discussing these APIs, and checking the minimum iOS version of each API you mention signals real production experience.
Architecture Patterns: MVVM, TCA, and When to Choose Each
Architecture questions test judgment. There is no single correct pattern, so the goal is to state a choice and defend it.
MVVM (Model-View-ViewModel) puts presentation logic in a view model that the view observes. With @Observable and @MainActor, it is lightweight and fits SwiftUI naturally. It is the most common answer and rarely a wrong one.
TCA (The Composable Architecture) is an open-source library from Point-Free that models features as state, actions, and a reducer, with side effects described as effects and dependencies injected for testing. Its strengths are predictable state changes and exhaustive testing; its costs are a learning curve, boilerplate, and a third-party dependency. The TCA repository documents its current APIs.
| Factor | MVVM | TCA | Coordinators + MVVM (UIKit) |
|---|---|---|---|
| Learning curve | Low | High | Medium |
| Testability | Good with DI | Excellent, exhaustive | Good |
| Boilerplate | Low | Medium to high | Medium |
| Team scale | Any | Teams that agree on conventions | Large UIKit apps |
| Screen flow | NavigationStack paths | State-driven navigation | Coordinator objects |
A strong answer sounds like: "For a five-person team shipping fast, I would use MVVM with a repository layer and protocol-based dependencies for tests. If the app had complex multi-step flows and the team wanted exhaustive state tests, TCA would be worth the ramp-up." If you are asked about classic patterns like delegate, observer, or factory, review design patterns interview questions beforehand.
iOS System Design Interview: An Offline-First Feed App
An iOS system design interview asks you to design the client side of a product, such as a news feed, chat app, or photo gallery. It differs from backend design: the interviewer cares about networking under bad conditions, local persistence, battery, memory, and app lifecycle more than database sharding. The general method in how to ace a system design interview still applies; here is the mobile version, worked end to end.
Prompt: Design the iOS client for a social feed. Users scroll an infinite feed, like posts, and should see content instantly on launch, even offline.
Step 1: Requirements (5 minutes)
- Functional: paginated feed, post detail, like/unlike, pull to refresh, images.
- Non-functional: cold launch shows cached content immediately, likes work offline and sync later, smooth scrolling on older devices, bounded disk and memory usage.
- Out of scope (say it out loud): posting, comments, notifications.
Step 2: Architecture
+--------------------------------------------------------------+
| UI Layer (SwiftUI) |
| FeedView -> PostRow -> AsyncImage-style CachedImageView |
+-----------------------------+--------------------------------+
| observes
+-----------------------------v--------------------------------+
| FeedViewModel (@MainActor, @Observable) |
| state: posts, isLoading, error, nextCursor |
+-----------------------------+--------------------------------+
| async calls
+-----------------------------v--------------------------------+
| FeedRepository (single source of truth = local store) |
| reads -> LocalStore writes -> LocalStore + Outbox|
+-------+---------------------------+--------------------------+
| |
+-------v---------+ +--------v-----------+ +----------------+
| LocalStore | | SyncEngine (actor) |-->| APIClient |
| SwiftData/SQLite|<-------| fetch pages, | | URLSession, |
| posts, cursors, | | drain outbox, | | retries, auth |
| outbox table | | resolve conflicts | +----------------+
+-----------------+ +--------------------+
^
+-------+---------+
| ImagePipeline | memory cache (NSCache) -> disk cache -> network
+-----------------+
The key decision is that the local store is the single source of truth. The UI never renders network responses directly. The sync engine writes server data into the store, and the view model observes the store. This makes offline mode the default path rather than a special case.
Step 3: Deep dives interviewers push on
- Pagination. Use cursor-based pagination, not offsets, because new posts shift offsets. Store
nextCursoralongside cached pages. Trigger the next page when the user is a few rows from the end. - Offline likes. Apply the like optimistically in the local store, append an outbox entry
{postId, action, clientTimestamp, idempotencyKey}, and let the sync engine drain the outbox when connectivity returns (observe it withNWPathMonitor). The idempotency key prevents double likes on retry. - Conflicts. For likes, last-write-wins per user per post is acceptable. Mention that edits to shared content would need server versions or timestamps to detect conflicts.
- Images. Two-tier cache:
NSCachein memory (purged under memory pressure) and a size-capped disk cache with LRU eviction. Request thumbnails sized for the cell, and cancel downloads for cells that scroll off screen. - Cache eviction. Keep the most recent few hundred posts on disk; prune on launch or in a background task.
- Background refresh. Use
BGAppRefreshTaskto prefetch the first page so cold launch feels fresh, while accepting that the system decides when it runs. - Observability. Log sync failures, outbox depth, and scroll hitches; ship risky changes behind feature flags because you cannot force users to update the app.
For the server half of this problem, the news feed system design walkthrough covers fan-out and ranking, which senior interviewers sometimes ask you to sketch briefly.
Take-Home and Live Coding Tips for iOS Interviews
Practical iOS rounds reward clean, working code over clever code. The classic prompt is "fetch JSON from this endpoint and show it in a list with images, loading, and error states."
For live coding:
- Model the response with
Codablestructs first, then the service, then the view. Narrate each step; thinking out loud is graded as heavily as the code. - Handle the four states: idle, loading, loaded, failed. Interviewers notice when error and empty states are missing.
- Use
async/awaitwithURLSession.shared.data(from:)and mark the view model@MainActor. - Keep Xcode previews working with a mock service; it shows you design for testability.
For take-homes:
- Follow the brief exactly, then add one thoughtful extra (offline caching or accessibility), not five.
- Write a handful of focused unit tests for the view model and parsing. Swift Testing (
@Test,#expect) or XCTest are both fine; say why you chose one. - Include a short README explaining architecture decisions and what you would do with more time.
- Support Dynamic Type and VoiceOver labels. Accessibility is a cheap signal of seniority.
The broader take-home coding assignment guide covers time-boxing and how reviewers score submissions. If you also interview for Android roles, the Android developer interview guide maps the same topics to Kotlin and Jetpack Compose.
A 4-Week iOS Interview Prep Plan
A focused four-week plan is enough for most working iOS engineers.
| Week | Focus | Output |
|---|---|---|
| 1 | Swift fundamentals, ARC, generics, protocols | Explain 20 core questions out loud in under 2 minutes each |
| 2 | Concurrency and SwiftUI data flow | Convert a GCD-based feature to async/await and actors |
| 3 | Coding practice in Swift | 25-30 medium problems plus 2 timed "build a list screen" drills |
| 4 | Architecture and mobile system design | Whiteboard the offline feed, a chat app, and a photo uploader |
Behavioral rounds still decide close calls, so prepare four or five stories about shipping, debugging a production crash, and disagreeing with a design decision.
Want a second brain in your next iOS loop? TechScreen listens to the question and suggests Swift code, SwiftUI fixes, and system design talking points in real time, invisible during screen shares. Try it with 3 free tokens, no credit card required.
Frequently Asked Questions
What are the most common iOS interview questions in 2026?
Expect questions on value versus reference types, optionals, protocols with associated types, ARC and retain cycles, async/await, actors and Sendable, SwiftUI state management with @State and @Observable, and when to drop down to UIKit. Mid-level and senior loops add an architecture discussion (MVVM, TCA, or coordinators) and a mobile system design round, usually an offline-capable feed, chat, or photo app. Live coding is typically a small UI feature or a LeetCode-style medium in Swift.
Do iOS interviews still ask LeetCode questions?
Many do. Large tech companies often include at least one general algorithms round that iOS candidates can usually take in Swift, typically at medium difficulty, though this varies by team. Smaller companies and startups more often replace it with a practical exercise: build a list screen from a JSON API, fix a bug in a sample app, or extend a take-home. Prepare both, but weight your time toward the format your recruiter confirms.
Should I learn SwiftUI or UIKit for iOS interviews?
Learn both, with SwiftUI as your default for new screens and UIKit as the fallback you can explain. Most production apps in 2026 are hybrids, so interviewers want to see that you understand SwiftUI's data flow and view identity, and that you can still use UIHostingController, UIViewRepresentable, and UICollectionView when SwiftUI hits a limit. Saying 'I only know SwiftUI' is a risk for any role touching a mature codebase.
What is the difference between an actor and a class in Swift?
An actor is a reference type that protects its mutable state by allowing only one task at a time to run code that touches that state. Calls from outside the actor are asynchronous and must be awaited, which lets the compiler rule out data races. A class has no such isolation, so concurrent access needs locks or a serial queue. Actors are reentrant, so state can change across an await inside an actor method.
How do I answer an iOS system design interview question?
Start with requirements and constraints that are specific to mobile: flaky networks, limited battery and memory, app lifecycle, and backward compatibility with old app versions. Then sketch layers: UI, view models, a repository, a local persistence store, and a sync engine talking to the API. Spend most of the time on the offline story, pagination, caching, and conflict handling. Close with observability, testing, and how you would roll out with feature flags.
How long should I prepare for an iOS developer interview?
Experienced iOS engineers usually need four to six weeks of focused preparation: one to two weeks refreshing Swift and concurrency fundamentals, one to two weeks of coding practice in Swift, and one to two weeks on architecture and mobile system design. Newer developers should plan longer and build one complete small app with networking, persistence, and tests, because interviewers often ask follow-up questions about your own project.
Ready to use AI assistance in your next interview?
TechScreen is the invisible AI assistant trusted by engineers interviewing at Google, Meta, Amazon, and hundreds of other companies. Start with 3 free tokens — no credit card required.
Ace your next interview →