Platform & distribution cheat sheet

The 18 Platform & distribution interview answers in 30 seconds each, plus quick facts. Printable, free.

One page per topic: print it or save it as PDF from your browser's print menu. Practise these questions

App and scene lifecycle states

An app is not running, inactive (in the foreground but not receiving events, for example during a call alert or while transitioning), active, in the background (running code briefly or for an allowed reason), or suspended (in memory but not running). With scenes, each window gets its own callbacks such as sceneDidBecomeActive and sceneDidEnterBackground; SwiftUI exposes them through scenePhase.

How push notifications are delivered

The app asks for permission with UNUserNotificationCenter, registers with registerForRemoteNotifications(), and receives a device token in application(_:didRegisterForRemoteNotificationsWithDeviceToken:). It sends the token to your server. The server sends a JSON payload to APNs over HTTP/2, authenticated with a token (JWT) or certificate, and APNs delivers it to the device, which shows it or wakes the app.

Background work with BGTaskScheduler

Register task identifiers (listed in Info.plist under BGTaskSchedulerPermittedIdentifiers) at launch, then submit requests: BGAppRefreshTaskRequest for short refreshes, BGProcessingTaskRequest for longer maintenance that can require power or network. The system decides when to run them. In the handler, set an expiration handler, call setTaskCompleted, and schedule the next request.

Getting the user's location

Add the usage description to Info.plist, request when-in-use permission with CLLocationManager, and ask for the accuracy you need. On iOS 17+, CLLocationUpdate.liveUpdates() gives an async sequence of updates; for a single fix, take the first update or use requestLocation(). Ask for Always permission only for features that truly need background location.

Region monitoring and geofencing

Region monitoring tells the app when the device enters or exits a circular area, even when the app isn't running. On iOS 17+, use CLMonitor with CircularGeographicCondition and iterate its events asynchronously. An app can monitor up to 20 conditions at once, so for many places monitor the nearest ones and update the set as the user moves.

Map annotations in SwiftUI and MapKit

In SwiftUI (iOS 17+), build map content inside Map { }: Marker for the standard balloon with a title or symbol, and Annotation for any custom SwiftUI view, plus overlays like MapCircle and MapPolyline. In UIKit, add MKAnnotation objects to MKMapView and provide views through mapView(_:viewFor:) with reuse and clustering.

The App Store review process

You upload a build through Xcode or Transporter, fill in metadata, privacy details and review notes in App Store Connect, and submit; Apple reviews it against the App Review Guidelines, usually within a day or two. Common rejections are crashes, incomplete features, missing demo accounts, misleading metadata, privacy problems, missing in-app account deletion, and digital purchases outside in-app purchase.

Code signing and provisioning profiles

Code signing proves who built the app and that it wasn't changed. A certificate (Apple Development for running on devices, Apple Distribution for TestFlight and the App Store) holds your signing identity. A provisioning profile ties together the App ID, the certificate, entitlements such as push or App Groups, and, for development and ad hoc, the allowed devices. Automatic signing in Xcode manages most of this.

Mixing Swift and Objective-C

Objective-C reaches Swift through the generated <ModuleName>-Swift.h header, which includes Swift declarations that are exposed with @objc (classes need to inherit from NSObject). Swift reaches Objective-C in an app target through a bridging header, or in a framework through its umbrella header and module map. Nullability annotations and NS_SWIFT_NAME make Objective-C APIs read well in Swift.

KVC and KVO

Key-Value Coding reads and writes properties by string key on NSObject subclasses. Key-Value Observing notifies you when an observable property changes. In Swift, KVO requires an NSObject subclass with @objc dynamic properties, and you use the block API observe(\.property, options:), which returns an NSKeyValueObservation you must keep. It is still useful for Apple types like AVPlayerItem.status.

Reliable universal links

Serve the apple-app-site-association file at /.well-known/ over HTTPS with no redirects, add the applinks: associated domain, and handle links in every entry point: scene connection options on cold start, scene(_:continue:) when running, or .onOpenURL / .onContinueUserActivity in SwiftUI. Parse the URL into a route, store it if the user must log in first, and deliver it to the right scene after login.

Routing a notification tap on cold start

Set the UNUserNotificationCenter delegate before application(_:didFinishLaunchingWithOptions:) returns, so userNotificationCenter(_:didReceive:) receives the tap even on cold start. Turn the payload into a route and hand it to the same router used for deep links; if the UI or login isn't ready yet, queue the route and deliver it once it is.

Background sync without draining the battery

Save edits locally first and queue them. Sync opportunistically: when the app is active, in a BGProcessingTask that requires network (and optionally power), or with a discretionary background URLSession. Batch changes into few requests, back off on failures, and avoid timers, frequent silent pushes or continuous location to keep the app awake.

Fixing a location feature that drains the battery

Measure first with the Energy instrument and Organizer. Then use the least power that meets the need: lower desiredAccuracy, a distanceFilter, the right activityType with automatic pausing, significant-change or CLMonitor conditions instead of continuous GPS, and stop updates when the feature isn't visible or needed. Avoid background location unless the feature depends on it.

Restoring navigation after the system kills the app

Save a small, codable description of where the user was, not the views themselves. In SwiftUI, store a route path (for example NavigationPath's codable representation or an array of route enums) in @SceneStorage. In UIKit, return an NSUserActivity from stateRestorationActivity(for:) and rebuild the stack from it on connection. Re-fetch data by id and handle items that no longer exist.

What an audio app must handle

Configure AVAudioSession with the playback category and enable the audio background mode. Handle interruptions such as calls and alarms, and route changes such as unplugging headphones, where you should pause. Publish Now Playing info and handle remote commands from the Lock Screen, Control Center and headphones, and support AirPlay and Siri where it fits.

Analytics that respect privacy

Collect only the events you'll use, without personal data, and prefer aggregated or anonymous identifiers. Declare collected data in App Store privacy labels and the privacy manifest, including what your SDKs collect. If data is linked with other companies' data for ads, that is tracking and needs App Tracking Transparency permission. Give users a way to opt out and honour it.

Syncing a phone app and a watch app

Give each side its own local store so it works alone, and sync changes when possible. With WatchConnectivity, use updateApplicationContext for the latest state (only the newest copy is kept), transferUserInfo for a queue of changes that must all arrive, transferFile for files, and sendMessage only when the counterpart is reachable. Resolve conflicts with timestamps or per-field rules, or sync both through your server or CloudKit.

Quick facts

NSObject
The Objective-C root class. Swift classes inherit from it for Objective-C interop, KVO, selectors and some Apple APIs.
Background modes
Audio, location, VoIP, external accessory and others must be enabled in capabilities and used for their real purpose.
Notification Service Extension
Runs for pushes with mutable-content: 1 and can modify content or download attachments within a short time.
CLMonitor
iOS 17's async API for geographic and beacon conditions, limited to 20 conditions per app.