iOS interview questions
iOS questions a Mobile developer can be asked, from first job to senior. Open one to see the strongest answer and why it works.
A form’s submit button sits under the home indicator and the keyboard. What is wrong?
The strongest answer: The layout ignores safe area and keyboard insets — I inset the content and keep the primary action visible while typing
Why it works: Exactly. Safe area and keyboard avoidance are part of shipping a phone UI — web or native.
- Respect safe areas.
- Avoid the keyboard; do not cover the action.
- Do not shrink type to cheat the layout.
- This is the same judgement as a responsive web form.
A crash report says “unexpectedly found nil while unwrapping an Optional value” on the profile screen.
What does that message mean, and what do you change?
The strongest answer: An optional that was nil got force-unwrapped. I handle the nil case instead — bind it or give it a default — and keep the force only where nil genuinely cannot happen
Why it works: Right — an optional is the compiler telling you a value may be missing; forcing it is a promise you have to keep.
- Nil was forced; handle it instead.
- Bind the optional or default it.
- Force only a true invariant.
- Fix where the nil comes from.
Product wants the push-permission dialog on first launch. What do you recommend?
The strongest answer: Wait until the user has a reason to care — a saved search, an order, a mention — then ask, and have a settings path if they decline
Why it works: Exactly. Context beats a cold prompt. A deny-forever on minute one is expensive to undo.
- Ask when the value is obvious.
- One system prompt; then settings.
- Do not re-prompt in a loop.
- Do not send push the user did not allow.
On iOS, what belongs in viewDidLoad and what belongs in viewWillAppear?
The strongest answer: viewDidLoad runs once when the view is created, so one-time setup goes there. viewWillAppear runs every time the screen is shown, so refreshing data the user may have changed elsewhere goes there
Why it works: Exactly — once versus every appearance. That one distinction decides where any line of setup belongs.
- Once versus every appearance.
- viewDidLoad: one-time setup.
- viewWillAppear: refresh what can change.
- Never rebuild the view each time.
iOS: you need an IDFA for a paid ads SDK. When do you show App Tracking Transparency?
The strongest answer: After a real explanation, before the SDK reads the identifier — and I have a product that still works if they say no
Why it works: Exactly. ATT is a gate. No means no, and the app must still function.
- Explain, then prompt.
- Honour a deny.
- Do not fingerprint around ATT.
- The app works without IDFA.
Product wants the whole article in the push payload. What do you say?
The strongest answer: Payloads are small and may be truncated or dropped — send an id, fetch on open, and do not put secrets or full PII in the notification
Why it works: Exactly. Notifications are a ping plus context, not a CDN.
- Id in the payload, body from the API.
- No secrets on the lock screen.
- Respect size limits.
- Do not abuse silent push as a socket.
A user reinstalls. Their “remember me” token is still in the Keychain. Is that a bug?
The strongest answer: It can be platform-correct — Keychain can survive reinstall — so I choose explicitly: wipe on uninstall via an accessibility / first-run flag, or treat it as a feature and say so
Why it works: Exactly. Survivability is a product decision. Be explicit; do not discover it in a security review.
- Know that Keychain can outlive the app.
- Pick wipe vs persist on purpose.
- Offer a real sign-out that deletes the item.
- Document it for support and security.
A launch-day push must reach millions. Where does the hard part live?
The strongest answer: On the send path: fan-out, token hygiene, quiet hours, and a collapse key — the client just registers and displays; I will not put business logic in the notification service worker of the phone
Why it works: Exactly. Scale is a backend / provider problem. The app stays a good citizen.
- Fan-out and hygiene on the server.
- Collapse / collapse keys for noisy events.
- Respect quiet hours and permission.
- The client displays; it does not orchestrate the blast.
A Core Data import running from a background sync crashes at random, mostly in release builds.
What do you suspect first?
The strongest answer: A managed object or context used off the queue that owns it. Contexts are confined to their queue, so the import runs on a background context and only object ids cross between them
Why it works: Exactly — contexts and their objects belong to one queue, and passing object ids is the supported way across.
- Contexts are queue-confined.
- Background work, background context.
- Pass object ids between queues.
- Never share objects across queues.
Product wants to promise the app’s data is already fresh every morning, using iOS background app refresh.
What do you commit to?
The strongest answer: Background refresh is opportunistic — the system decides whether it runs and the user can switch it off — so I promise a fast refresh when the app opens and treat a background run as a bonus
Why it works: Right — you can ask, not schedule, so the product promise has to sit on the path you control.
- Background runs are opportunistic.
- Never promise a background schedule.
- Make the open-time refresh fast.
- Treat background work as a bonus.
You own a large UIKit app. A team wants to build the new subscription flow in SwiftUI.
What is your call, and what do you write down?
The strongest answer: Yes for a self-contained new flow hosted inside the existing navigation — with the interop seam written down, a minimum OS version agreed, and an owner for when a SwiftUI screen misbehaves
Why it works: Right — the two interoperate in both directions, so the question is not “can we” but where the seam sits and who owns it.
- Adopt in a bounded, owned slice.
- Pick one self-contained flow.
- Write down the interop seam.
- Agree the minimum OS version.
Every squad added its own push provider. What do you do?
The strongest answer: One registration path, one token store, one quiet-hours / consent story, and a fan-out service the squads publish into — I do not let five SDKs fight for the device token
Why it works: Exactly. Push is a platform. Tokens, consent, and send are shared infrastructure.
- One token, one consent.
- Squads publish events; platform sends.
- Quiet hours are company-wide.
- Do not embed five providers.