Interview guides / ios
Apple-Style iOS Engineer Interview Questions
Unofficial Apple-style iOS interview prep: Swift depth, API design, performance, and platform fundamentals with example answers.
Unofficial guidance only. Apple interview loops vary by team and AceMobileInterview is not affiliated with Apple.
Expect strong Swift fundamentals, careful API design thinking, performance awareness, and clear communication. Some teams go deep on algorithms; many care a lot about craft and platform knowledge.
1.How do you design a Swift API that is hard to misuse?
Prefer value types where possible, exhaustive enums for states, meaningful type names, avoid Stringly-typed APIs, use ownership semantics clearly (weak delegates), and make illegal states unrepresentable. Document threading expectations.
2.Explain ARC and how you prevent retain cycles in closures.
ARC frees at zero strong refs. Cycles often appear in escaping closures capturing self. Use [weak self] when lifetime is uncertain, unowned only when guaranteed. Break parent-child ownership carefully with weak back-references.
3.Walk through the UIViewController lifecycle and where you would load data, configure UI, and clean up observers.
loadView → viewDidLoad (one-time setup) → viewWillAppear → viewIsAppearing → viewDidAppear → viewWillDisappear → viewDidDisappear → deinit. Load remote data after first appear or via a dedicated loader; remove NotificationCenter/KVO observers in deinit or viewDidDisappear depending on scope; cancel in-flight tasks when the screen disappears if results are no longer needed.
4.When do you pick delegate patterns vs completion closures?
Delegates suit multi-method ongoing relationships (tableView). Closures suit one-shot results. Avoid retain cycles: weak delegates, weak self captures.
5.What does iOS sandboxing restrict?
Apps can’t freely read other apps’ data; limited filesystem, entitlements for capabilities (iCloud, push, associated domains). Privacy manifests/permissions gate sensitive APIs.
6.What are common NotificationCenter bugs and how do you avoid them?
Forgetting to remove observers (pre-block API), posting on wrong threads, overusing global events. Prefer Combine publishers, delegates, or scoped observers; always consider lifecycle.
7.What is KVO and what replaced it in many Swift codebases?
KVO observes Obj-C property changes. Prefer Combine, Observation/@Observable, delegates, or closures for Swift-first code. KVO still appears with AVFoundation and legacy APIs.
8.How does cell reuse work and what bugs does it cause?
Cells dequeue from a reuse pool; configure every visible field in cellForRow or configure methods. Stale images/text appear if you don’t reset state; cancel image loads on prepareForReuse.
9.When would you use Result<Success, Failure> instead of throws?
Result is great for async callbacks and stored outcomes. throws fits synchronous APIs and async/await. You can bridge with get() / mapError depending on call site style.
10.How do optionals work, and when would you use ?, !, if let, guard let, and ??
Optionals wrap absence of a value. Prefer if let/guard let for safe unwraps; ?? for defaults; avoid force unwrap (!) except when truly impossible to be nil. Optional chaining (?.) short-circuits safely.
11.Explain value types vs reference types and how copying behaves.
Value types (struct/enum) copy on assignment; reference types share one instance. Mutations to a copy don’t affect the original. Copy-on-write optimizes large values like Array/Dictionary/String.
12.When do you choose a struct over a class in Swift?
Prefer structs for value semantics, thread-safer copies, and simple data. Use classes for identity, inheritance, Objective-C interop, or shared mutable references. Many modern models are structs; UIKit types remain classes.
13.What is ATS and when can you exception it?
ATS enforces HTTPS/TLS best practices. Exceptions via Info.plist for legacy servers are discouraged and scrutinized. Prefer fixing server TLS over broad NSAllowsArbitraryLoads.
14.Explain Automatic Reference Counting (ARC). When do retain cycles happen, and how do you break them with weak and unowned references?
ARC tracks strong references and frees objects at zero. Cycles usually appear in closures capturing self, or parent↔child object graphs. Use weak for optional back-references (delegates, closures that may outlive the object) and unowned when the reference is non-optional and guaranteed to outlive the capture. Always capture lists in escaping closures: `[weak self]`.
15.Compare GCD (DispatchQueue) with async/await and actors. When would you still reach for GCD?
GCD is queue-based concurrency; Swift Concurrency models tasks, structured cancellation, and actor isolation for data races. Prefer async/await for new code, MainActor for UI, and actors for shared mutable state. GCD still helps for fine-grained QoS tuning, integrating C APIs, or migrating legacy code incrementally.
16.How do generics and associated types differ in Swift?
Generics parameterize types/functions (Array<Element>). Associated types parameterize protocols (IteratorProtocol.Element). Use type erasure (any/some) when you need existential flexibility.
17.Compare throws, Result, and async throws for networking layers.
Prefer async throws for modern networking. Result suits completion handlers. Map domain errors distinctly from transport errors; avoid catching and swallowing without logging/telemetry.
Keep going with AceMobileInterview
Reading helps. Timed practice locks it in. Jump into the interactive track for algorithms with LeetCode links, studio projects, debugging zips, and mobile system design.