iOS interview practice
Real interview questions as two-minute exercises. Commit to an answer first, then check it and read the full explanation with current Swift code.
Prefer to just read? Every question has Show answer. Progress is saved on this device only.
- PredictPick what you think happens, or tap the line with the bug.
- CheckSee whether you were right, and why every other option is wrong.
- Learn itRead the 30-second answer, then the deep dive and follow-ups.
– interview-ready · 192 questions
– of 192 tried
Saved on this device. Interview-ready means you got it right on two different days. Guesses and hints count for less.
Daily 5
The same five questions for everyone today, with a grid to share. Needs JavaScript. Start with the first question.
Readiness by topic
Your progress is saved in this browser only. With JavaScript on, this shows each topic's readiness and lets you export your progress to a file or import it on another device.
Share your progress
Topics
Concurrency
async/await, tasks, actors, Sendable and the Swift 6.2 defaults, plus the GCD questions interviewers still ask.
17 questions
SwiftUI
State ownership, Observation, view identity, navigation, layout and the SwiftUI bugs interviewers love to show you.
22 questions
Swift language
Optionals, value semantics, protocols, generics, closures, error handling and the modern Swift features interviews test.
23 questions
Memory & ARC
How ARC counts references, how retain cycles form and break, weak vs unowned, and how to find leaks.
7 questions
UIKit
View controller lifecycle, Auto Layout, lists and collections, hit-testing and navigation in UIKit.
13 questions
Networking
URLSession with async/await, Codable, retries, background transfers, testable network layers and image pipelines.
11 questions
Combine
Publishers, operators and subscribers, cancellation, timing operators, errors, testing, and when to pick async/await instead.
12 questions
Persistence
Choosing storage, UserDefaults, Keychain, Core Data, SwiftData, files, migrations and safe data cleanup.
10 questions
Architecture & patterns
MVC to TCA, MVVM done right, coordinators, dependency injection, classic patterns and modularization.
9 questions
Testing
XCTest and Swift Testing, async and concurrent tests, test doubles, UI tests, TDD and LLDB.
8 questions
Security
Defence in depth on iOS: Keychain, pinning, biometrics, sandboxing, secrets and end-to-end encryption.
7 questions
Performance
Profiling with Instruments, smooth scrolling, rendering, launch time, app size and measuring before fixing.
10 questions
Platform & distribution
App lifecycle, push, background work, location, deep links, signing, App Review, interop and device integrations.
18 questions
Modern platform
Widgets, App Intents, Live Activities, StoreKit 2, privacy manifests, Liquid Glass, previews and on-device models.
9 questions
Accessibility & localization
VoiceOver, Dynamic Type, accessible custom components, String Catalogs, formatting and right-to-left layouts.
6 questions
System design scenarios
Big-tech style design rounds: feeds, caches, offline-first, maps, media, payments, chat and incident response.
10 questions
All questions
Concurrency
- Sequential await vs async letPredict · timeline
- async/await vs completion handlersPick the fix
- async let vs TaskGroupPick the fix · timeline
- Cooperative cancellationPredict · timeline
- Task {} vs Task.detachedPick the fix
- What is an actor?Pick the fix
- Actor reentrancy: check, await, then actPredict · timeline
- @MainActor view modelsSpot the bug
- Sendable and Swift 6 strict checkingPick the fix
- Swift 6.2: default MainActor and @concurrentPredict
- Mutex vs actorPick the fix
- Serial vs concurrent queuesPredict
- DispatchQueue.main.sync on the main threadPredict
- Reader-writer with a barrier vs an actorSpot the bug
- Bridging callbacks with AsyncStreamPredict
- OperationQueue vs GCDPick the fix
- Single-flight token refreshPick the fix
SwiftUI
- SwiftUI vs UIKit: key differencesPredict
- Which property wrapper for which data?Pick the fix
- @State vs a plain varPredict
- @StateObject vs @ObservedObjectPredict
- @Observable model keeps resettingSpot the bug · Pick the fix
- @Observable vs ObservableObjectPredict
- @Bindable for passed-in modelsPick the fix
- @Binding and the $ prefixPick the fix
- View identity: if/else vs a modifierPredict
- Why body runs often, and keeping it cheapPredict
- .task vs .onAppear + TaskSpot the bug
- .task(id:) and built-in debouncingPredict
- NavigationStack and deep linksPick the fix
- Custom environment values with @EntryPick the fix
- ViewModifier vs AnyViewPick the fix
- .animation(_:value:) vs withAnimationPredict
- GeometryReader vs ViewThatFits and LayoutPick the fix
- UIViewRepresentable feedback loopsSpot the bug
- Loading and error state in SwiftUISpot the bug
- @FocusStateFill the blank
- @ViewBuilderPick the fix
- A timer that re-renders the whole screenPick the fix
Swift language
- Optionals and why Swift has themPredict
- Value types vs reference typesPredict
- Protocols vs abstract classesPick the fix
- Closures and capture listsPredict
- @escaping vs non-escaping closuresPick the fix
- GenericsPick the fix
- Associated types and primary associated typesPick the fix
- Enums with associated and raw valuesPredict
- willSet and didSetPredict
- Stored, computed and lazy propertiesPredict
- The defer statementPredict
- Result and typed throwsPick the fix
- inout parametersPredict
- Key pathsPick the fix
- Opaque types (some) vs existentials (any)Pick the fix
- @autoclosurePredict
- Copy-on-writePredict
- Property wrappersFill the blank
- == vs ===Predict
- Swift macrosPick the fix
- Phantom typesPick the fix
- HashableSpot the bug
- Noncopyable types (~Copyable)Pick the fix
Memory & ARC
- How ARC worksPredict
- Retain cycles and how to break themSpot the bug
- Retain cycles in closuresSpot the bug
- weak vs unownedPick the fix
- Autorelease pools todayPick the fix
- Finding memory leaksOrder the steps
- Responding to memory pressurePick the fix
UIKit
- The UIViewController lifecycleOrder the steps
- How Auto Layout worksPick the fix
- Content hugging and compression resistancePredict
- frame vs boundsPredict
- Table and collection view cell reuseSpot the bug
- UICollectionView vs UITableView and diffable data sourcesPick the fix
- UICollectionViewCompositionalLayoutPick the fix
- layoutSubviewsPick the fix
- Hit-testing and the responder chainPredict
- Passing data between view controllersPick the fix
- Modal presentation stylesPredict
- viewDidLoad vs initPick the fix
- intrinsicContentSizeFill the blank
Networking
- Making a network requestSpot the bug
- POST requests with a JSON bodyFill the blank
- Codable and mismatched keysPredict
- Retries with exponential backoffPick the fix
- App Transport Security (ATS)Pick the fix
- A testable network layerPick the fix
- URLSessionConfigurationPick the fix
- Rate limits and temporary outagesPick the fix
- Resilient large downloadsPick the fix
- Reliable photo uploadsPick the fix
- A fast image-loading pipelineOrder the steps
Combine
- What Combine is forPick the fix
- Publishers, operators and subscribersOrder the steps
- AnyCancellable and subscription lifetimeSpot the bug
- debounce vs throttlePredict
- combineLatestPredict
- merge vs zipPredict
- Error handling in CombinePredict
- eraseToAnyPublisherPick the fix
- PassthroughSubject vs CurrentValueSubjectPick the fix
- Testing Combine publishersPick the fix
- Combine vs async/awaitPick the fix
- Preventing stale search resultsSpot the bug
Persistence
- Choosing the right storagePick the fix
- Using UserDefaults correctlyPick the fix
- Storing secrets in the KeychainFill the blank
- The Core Data stackOrder the steps
- Core Data and threadingPick the fix
- SwiftDataFill the blank
- Reading and writing filesPick the fix
- Rolling out a breaking schema changeOrder the steps
- Feature flags that change stored dataPick the fix
- What to remove on logoutPick the fix
Architecture & patterns
- MVC, MVVM, VIPER and TCA comparedPick the fix
- MVVM done rightSpot the bug
- The delegate patternPick the fix
- The observer patternPick the fix
- Factory and builder patternsPick the fix
- Dependency injectionSpot the bug
- Strategy and command patternsPick the fix
- The coordinator patternPick the fix
- Modularizing a growing appOrder the steps
Testing
- Writing good unit tests with XCTestSpot the bug
- Testing async codePick the fix
- Test-driven developmentOrder the steps
- Test doubles: stubs, spies, mocks and fakesPick the fix
- UI tests with XCUITestFill the blank
- Swift TestingFill the blank
- Testing concurrent code without sleepsPick the fix
- Debugging with LLDBPick the fix
Security
- The pillars of iOS app securityPick the fix
- Certificate and public key pinningPick the fix
- Face ID and Touch ID done securelyPick the fix
- Jailbreak detectionPick the fix
- Protecting API keysPick the fix
- App sandboxingPick the fix
- End-to-end encryption in a chat appPick the fix
Performance
- Profiling an iOS appPick the fix
- Dropped frames and hitchesPredict
- Smooth scrolling in listsPick the fix
- Offscreen renderingPick the fix
- Lazy loadingPick the fix
- Reducing app sizePick the fix
- Fixing a launch time regressionOrder the steps
- Measuring a slow screen without guessingPick the fix
- A 50,000-item list that stutters on updatesPick the fix
- From a tap to a pixel on screenOrder the steps
Platform & distribution
- App and scene lifecycle statesPredict
- How push notifications are deliveredOrder the steps
- Background work with BGTaskSchedulerPick the fix
- Getting the user's locationPick the fix
- Region monitoring and geofencingPick the fix
- Map annotations in SwiftUI and MapKitFill the blank
- The App Store review processPick the fix
- Code signing and provisioning profilesPick the fix
- Mixing Swift and Objective-CPick the fix
- KVC and KVOPick the fix
- Reliable universal linksPick the fix
- Routing a notification tap on cold startPick the fix
- Background sync without draining the batteryPick the fix
- Fixing a location feature that drains the batteryPick the fix
- Restoring navigation after the system kills the appPick the fix
- What an audio app must handlePick the fix
- Analytics that respect privacyPick the fix
- Syncing a phone app and a watch appPick the fix
Modern platform
- Building widgets with WidgetKitPick the fix
- App Intents and ShortcutsFill the blank
- Live ActivitiesOrder the steps
- In-app purchases with StoreKit 2Spot the bug
- Keeping subscription access correct everywherePick the fix
- Privacy manifestsPick the fix
- Adopting Liquid Glass in iOS 26Pick the fix
- SwiftUI previews with #Preview and @PreviewableFill the blank
- On-device models with Foundation ModelsPick the fix
Accessibility & localization
- Supporting VoiceOverFill the blank
- Supporting Dynamic TypePick the fix
- Localizing an iOS appPick the fix
- String Catalogs and pluralsPick the fix
- Making a custom card accessiblePick the fix
- Right-to-left languagesPick the fix
System design scenarios
- Designing an infinite-scroll social feedPick the fix
- A thread-safe LRU cachePredict
- Offline-first architectureOrder the steps
- A map with 10,000+ live pinsPick the fix
- Responding to a crash spikeOrder the steps
- An adaptive-bitrate player with Picture in PicturePick the fix
- A secure payment flowOrder the steps
- A 60 fps short-video feedPick the fix
- A chat timeline that survives retriesPick the fix
- A release that causes data lossOrder the steps