Skip to content

15 iOS Interview Questions for Hiring iOS Engineers in 2026

Cover: a pixel speech bubble reading 15 iOS Interview Questions next to the iOS logo, with the Wild.Codes W tile in the corner.

These 15 questions are for a CTO or engineering manager interviewing a senior iOS engineer in 2026. They cover Swift, concurrency and memory, UIKit and SwiftUI, offline data, testing and the release process. Each question says why to ask it, what a strong answer shows and the red flag to listen for. Pick five or six that match your app, and ask the candidate for a real case from their last project, since a definition is easy to memorise.

Two changes since 2024 shape the list. The Swift 6 language mode turns data-race warnings into compile errors (the Swift 6 migration guide covers what changes), and many apps that have been in the App Store for a few years now mix SwiftUI screens with older UIKit code. A candidate who knows only one of the two UI frameworks will struggle on that kind of codebase.

Four more questions, on Swift 6 data-race errors in a shared cache, a stuttering SwiftUI list, stopping work when the user leaves a screen and storing an auth token, are on our page about hiring iOS developers. This list does not repeat them.

The questions at a glance

AreaQuestionsWhat it tells you
Swift and architecture1-4Whether the candidate chooses types, errors and structure on purpose
Concurrency and memory5-8Whether async code and object lifetimes hold up under real use
UIKit and SwiftUI9-11Whether they can work in a codebase that has both and build for VoiceOver users
Lifecycle and data12-13Whether user data survives backgrounding, bad networks and conflicts
Testing and release14-15Whether they can ship safely without one person's laptop

Swift and architecture

1. When do you choose a struct over a class, and what happens when you copy a struct that holds a large array?

Why ask it: Value semantics decide how state moves through a SwiftUI app and how safely data can be shared between tasks. The answer shows whether the candidate reasons about ownership or picks types out of habit.

A strong answer shows: Structs for data that should be copied, such as models and view state, and classes when identity or a shared lifetime matters (a cache, a coordinator) or when an Objective-C API needs one. The candidate knows that Array, Dictionary and String are copy-on-write: assigning the struct shares the storage, and the copy happens on the first mutation. A senior candidate can explain how to give a custom type the same behaviour with isKnownUniquelyReferenced.

Red flag: "Structs are always faster because they live on the stack", or the belief that every assignment copies the whole array.

2. How do you choose between throws, Result and an optional return value?

Why ask it: Error handling decides what the user sees when the network or a decoder fails, and careless handling can hide a bug for months.

A strong answer shows: throws for failures the caller has to handle, an optional when a missing value is a normal outcome, and Result mainly where an outcome has to be stored or passed through a callback. Low-level errors are mapped to states the UI can show. The candidate knows that Swift 6 added typed throws (throws(ParseError)) and keeps it for closed sets of errors inside a module.

Red flag: try? everywhere, so failures turn into silent nil values, or one generic error alert for the whole app.

3. What is the difference between some Shape and any Shape in a function signature?

Why ask it: Opaque types and existentials appear in every SwiftUI body and in most networking layers. Mixing them up leads to type-erasure workarounds and slower code.

A strong answer shows: some is an opaque type: in a parameter it is shorthand for a generic, so the function works with one concrete type per call, and the compiler can usually specialise it and remove dynamic dispatch. any is an existential box that can hold different conforming types at run time, at the cost of dynamic dispatch and a heap allocation for larger values. The candidate reaches for some or a generic parameter first, uses any for a collection of different types, and can say why body is declared as some View.

Red flag: Wrapping views in AnyView or values in Any until the compiler stops complaining.

4. How would you structure a new feature in our app, and where do navigation, state and side effects live?

Why ask it: A list of pattern names tells you little. Asking where each concern lives shows whether the candidate can keep a feature testable as it grows.

A strong answer shows: A structure chosen for the app's size and the team, for example MVVM with a coordinator, The Composable Architecture, or plain SwiftUI views with small models, with the trade-off stated. Networking and persistence sit behind protocols or injected closures so tests can replace them, and navigation state has one owner.

Red flag: Naming MVC, MVP, MVVM and VIPER without an opinion on any of them, or putting networking, formatting and navigation in one view controller.

Concurrency and memory

5. How do you wrap an old callback-based API so the rest of the code can call it with async/await?

Why ask it: Apps that predate Swift concurrency are full of these bridges, and a broken one hangs a screen without a crash to point at.

A strong answer shows: withCheckedThrowingContinuation, resumed exactly once on every path, errors included. The candidate knows that a checked continuation stops the app if it is resumed twice and logs a warning if it is never resumed. If the old API can be cancelled, the bridge forwards cancellation with withTaskCancellationHandler, and a delegate API that delivers many events becomes an AsyncStream.

Red flag: Blocking a thread with a DispatchSemaphore until the callback arrives, or forgetting the error path so the caller waits forever.

6. At launch the app needs the user profile, the settings and the first page of a feed. How do you load them in parallel, and what happens if one fails?

Why ask it: Launch time is where users notice slowness, and the answer separates people who have used structured concurrency from people who have read about it.

A strong answer shows: async let for a fixed set of calls and a task group for a list whose length is known only at run time. The candidate knows that a child's error reaches the group only when the group awaits that child, that once the error is thrown out of the group the remaining child tasks are cancelled, and that an async let nobody awaited is cancelled and awaited when its scope ends. Whether a failed feed should block the profile is a product decision, and the candidate catches errors per call when a partial screen is better than an error screen.

Red flag: Three await lines in a row described as parallel, or every call wrapped in Task.detached.

7. An actor method reads its state, awaits a network call, then writes the state back. What can go wrong?

Why ask it: Actors prevent data races, yet the logic around an await can still interleave, and this bug passes every compiler check in Swift 6.

A strong answer shows: Actor reentrancy: at each await the actor can run other calls, so state read before the suspension may be out of date afterwards. The candidate checks the state again after the await, or stores the in-flight Task in a dictionary so a second caller waits for the same request instead of starting a duplicate.

Red flag: The belief that an actor makes the whole method atomic, the way a lock would.

8. How do you find and fix a retain cycle?

Why ask it: Leaks show up as memory warnings and as screens that keep doing work after they close, and they are hard to find without the tools.

A strong answer shows: Proof first, from the Xcode Memory Graph Debugger, the Leaks and Allocations instruments, or a deinit that never runs. The candidate knows the usual sources: an object that stores a closure capturing self strongly, a delegate property that is not weak, a Timer that retains its target, and a notification observer block that holds self. [weak self] is for an object that may already be gone and unowned only for a guaranteed lifetime. A Task whose closure uses self keeps the object alive until the task finishes, which matters for long-running loops.

Red flag: [weak self] added to every closure by reflex, non-escaping ones included, without checking whether there was a cycle.

UIKit and SwiftUI

9. Our app is mostly UIKit and the next screen will be SwiftUI. How do you integrate it, and how would you use a UIKit view inside SwiftUI?

Why ask it: Many apps that have been in the App Store for a few years have both frameworks, so this is often the first work a new hire meets.

A strong answer shows: SwiftUI embedded with UIHostingController, added as a child view controller with the containment calls. UIKit views wrapped in UIViewRepresentable or UIViewControllerRepresentable, with a coordinator for delegate callbacks. The candidate decides which side owns navigation and shares one observable model between the two parts of the app rather than syncing copies.

Red flag: Proposing to rewrite the app in SwiftUI first, or never having shipped the two side by side.

10. Who owns a view model in SwiftUI, and which property wrapper do you use for it?

Why ask it: Ownership bugs in SwiftUI show up as state that resets for no visible reason, and the right fix depends on the iOS versions you support.

A strong answer shows: With the Observation framework (iOS 17 and later), the model is marked @Observable, owned with @State in the view that creates it, passed down as a plain property, and wrapped in @Bindable where a child needs bindings. On older deployment targets the owner uses @StateObject and the views that receive the model use @ObservedObject. App-wide dependencies come through @Environment.

Red flag: @ObservedObject var model = Model() in the view that owns the model, so it is recreated whenever the parent view is rebuilt and loses its state.

11. How do you make a custom control, such as a rating slider, work with VoiceOver and Dynamic Type?

Why ask it: Accessibility is part of product quality, in some markets and sectors it is a legal requirement, and it is cheap only when it is built in from the start.

A strong answer shows: An accessibility label, value and traits on the control. For a slider, the adjustable behaviour: accessibilityAdjustableAction in SwiftUI, or the adjustable trait with accessibilityIncrement() and accessibilityDecrement() in UIKit. Fonts use text styles so they scale with Dynamic Type, and the candidate checks the screen with VoiceOver on and with Accessibility Inspector.

Red flag: Accessibility treated as a ticket for later, or never having turned VoiceOver on.

Lifecycle and data

12. What happens to your app when the user switches away, and where do you save state?

Why ask it: Lost drafts and half-finished uploads after the user switches apps are bugs users notice, and they come from wrong assumptions about the app lifecycle.

A strong answer shows: The scene-based lifecycle (sceneDidEnterBackground, or scenePhase in SwiftUI), the short time an app gets before it is suspended, and the fact that a suspended app can be terminated with no further callback. State is saved on the move to the background, beginBackgroundTask finishes a few seconds of work such as a save, a background URLSession carries uploads and downloads, and BGTaskScheduler handles refresh or processing that can wait. Navigation comes back through @SceneStorage or NSUserActivity.

Red flag: Relying on applicationWillTerminate to save data.

13. Users edit data offline on a flight. How do you store it, sync it later and resolve a conflict?

Why ask it: Offline behaviour is where apps lose user data, and a candidate who has shipped it will bring up conflicts before you ask.

A strong answer shows: The local store (SwiftData, Core Data, or SQLite through a library such as GRDB) is the source of truth for the UI, with a queue of pending changes that carry stable client-side IDs so a retry cannot create duplicates. Sync is retried with backoff, NWPathMonitor serves as a hint to try again sooner when the network comes back (a working path does not prove the server is reachable), and the conflict rule is agreed with the product team: last write wins, a field-level merge, or asking the user. With Core Data, the candidate knows that managed objects belong to their context, passes object IDs between threads, and writes in a background context.

Red flag: "We just retry the request", or managed objects passed between threads.

Testing and release

14. What do you unit test in an iOS app, and how do you test async code?

Why ask it: The answer tells you whether the codebase will be safer or more fragile a year after this person joins.

A strong answer shows: Tests for view models and business logic, with dependencies injected through protocols or closures, and UI tests kept for a few critical flows. Async code is tested with async test methods instead of sleeps. The candidate knows Swift Testing (@Test, #expect), which ships alongside XCTest since Xcode 16, and can name a bug that a test caught.

Red flag: No tests at all, or only UI tests full of sleep() calls.

15. Walk me through how a build gets from the main branch to users on the App Store.

Why ask it: A senior iOS engineer owns the release, and a broken signing setup can hold up a hotfix for days.

A strong answer shows: CI that builds and signs the app without anyone's laptop (Xcode Cloud, GitHub Actions or another CI, often with fastlane), with certificates and provisioning profiles managed for the whole team. Build numbers go up automatically, builds go to TestFlight first (external testers need Beta App Review), and dSYMs are uploaded so crash reports are symbolicated. The candidate uses phased release, which spreads an automatic update over seven days and can be paused, and knows when an App Store submission needs a privacy manifest.

Red flag: Only ever archiving and uploading by hand from Xcode, or a distribution certificate that lives on one machine.

How to run the interview

Five or six of these questions fill an hour once you leave room for follow-ups. Start each one with the candidate's own project ("tell me about a time this went wrong") and move to the hypothetical only if they have not met the problem. Bring a short piece of code from your own app, such as a view model or a networking call, and ask what they would change. Score each answer against the strong answer and the red flag above, and write the score down before the next question, while you still remember the details.

How Wild.Codes checks iOS engineers

In the Wild.Codes full search, engineers take a timed video interview for your role. AI writes the questions from your brief, each engineer gets about a minute to think before recording starts, and a talent manager checks the results. You watch the recordings and read the transcripts before your own interview, so your hour can go to the follow-up questions from this list. How our vetting works describes each step.

On the subscription, the first shortlist arrives within 47 hours of confirming the role. You can also hire an engineer as a permanent employee on your own payroll for a one-time fee, and there is no cost until you hire. Pricing covers both models. To start, describe your iOS role and see pre-selected engineers with a monthly rate on each.

For CTOs
For Founders
For Recruiters
For Product Managers
Laravel Developer’s Skills Described
• CSS, HTML, and JavaScript knowledge;
‍
• PHP expertise;

• Database management skills;

•Jungling traits, methods, objects, and classes;

• Agile & Waterfall understanding and use;

• Soft skills (a good team player, high-level communication, excellent problem-solving background, and many more)
Laravel Developer’s Qualifications Mentioned
• Oracle 12c, MySQL, or Microsoft SQL proficiency;

• OOP & MVS deep understanding;

• Knowledge of the mechanism of how to manage project frameworks;
‍
• Understanding of the business logic the project meets;

• Cloud computing & APIs expertise.
Laravel Developer’s Requirements to Specify
• Self-motivation and self-discipline;

• Reasonable life-work balance;

• The opportunity to implement the server-side logic via Laravel algorithms;

• Hassle-free interaction with back-end and front-end devs;

• Strong debugging profile.
Front-End JS
Requirements:
• Building the client side of the website or app
‍
• Using HTML, XHTML, SGML, and similar markup languages

• Improving the usability of the digital product

• Prototyping & collaboration with back-end JS experts

• Delivery of high-standard graphics and graphic-related solutions
Skills & qualifications:
• HTML & CSS proficiency;
‍
• Using JS frameworks (AngularJS, VueJS, ReactJS, etc
‍
Back-End JS
Requirements:
• Be responsible for the server side of websites and apps

• Clean coding delivery and timely debugging & troubleshooting solution delivery

• UI testing and collaboration with front-end JS teammates
‍
Skills & qualifications:
• Node.js and another similar platform expertise
‍
• Database experience

• Building APIs while using REST or similar tech solutions
Full-Stack JS
Requirements:
• Expertise in client-side & server-side questions

• Collaboration with project managers and other devs

• Delivery of design architecture solutions

• Creation of designs & databases

• Implementation of data protection and web cybersecurity strategies.
Skills & qualifications:
• Leadership, communication, and debugging skills
‍
• Both front-end and back-end qualifications

CONTINUE READING

Privacy Preferences

Essential cookies — Google Analytics, Microsoft Clarity, Referly
Required
Marketing cookies
Personalization cookies
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.