Top 50 Swift Interview Questions 2026
Swift is Apple's primary language for iOS, macOS, and tvOS development. Candidates report that optionals, ARC memory management, closures, and async/await are...

What changed in 2026 drives
Mass-recruiter offer letters are flatter for 2026 batch - the 4-5 LPA ASE band has barely budged in three years while inflation eats real wages. Premium tracks (Digital, Pro, Elite, Specialist) are still where the differential lives, and they are entirely test-driven. If you are aiming higher than the default offer, the coding round is not optional pageantry - it is the entire interview.
What I'd actually study for this
- 01Two solid coding-round answers (1 medium-hard DSA each, with edge-case discussion) > five half-baked ones
- 02One real project you can defend end-to-end - file paths, design decisions, and what you would change
- 03One DBMS schema you actually built (not a textbook ER diagram), with at least 3 join-heavy queries written from memory
- 04Three behavioural STAR stories: failure recovered, conflict handled, ownership taken
Where most candidates trip up
The single biggest mistake is treating company-specific guides as primary prep and DSA as secondary. It is the opposite. Mass recruiters use the test as a filter, but premium tracks at every IT services company use coding to allocate offer band. Spend 70% of prep time on DSA + system fundamentals, 20% on company-specific patterns, 10% on HR rehearsal. Reverse that ratio and you collect the default offer.
Editorial commentary by Aditya Sharma · written for PapersAdda · not generated, not aggregated.
Last Updated: June 2026 | Level: Freshers to 3 Years Experience | Read Time: ~22 min
Swift is Apple's primary language for iOS, macOS, and tvOS development. Candidates report that optionals, ARC memory management, closures, and async/await are the most frequently tested topics in iOS developer interviews. This guide covers 50 questions from language basics to advanced concurrency, with code examples and predict-the-output problems. Confirm current interview requirements on the official careers portal of the company you are targeting.
Pair with Flutter Interview Questions 2026 and React Native Interview Questions 2026 for cross-platform comparison.
Table of Contents
- Swift Basics (Q1-Q12)
- OOP and Protocols (Q13-Q22)
- Memory Management: ARC (Q23-Q29)
- Closures and Functional Programming (Q30-Q36)
- Concurrency: async/await and Actors (Q37-Q44)
- SwiftUI and Combine (Q45-Q50)
- Mock Interview: 5 Questions
- FAQ
Swift Basics
Q1. What is Swift and what are its key features? Easy
- Optionals for explicit null handling
- Type inference
- Automatic Reference Counting (ARC) for memory management
- Protocol-oriented programming
- Generics
- Modern concurrency with async/await and actors
Q2. What is the difference between let and var? Easy
let name = "Aditya" // constant, immutable
// name = "other" // compile error
var count = 0 // variable, mutable
count += 1 // ok
// Value types (struct): let makes the WHOLE struct immutable
struct Point { var x, y: Int }
let p = Point(x: 1, y: 2)
// p.x = 5 // error - p is a constant
var q = Point(x: 1, y: 2)
q.x = 5 // ok
Q3. What are Optionals in Swift? Easy
var name: String? = nil
name = "Aditya"
// Optional binding (safe unwrap)
if let n = name {
print("Name is \(n)")
}
// Guard (early exit)
func greet(name: String?) {
guard let n = name else {
print("No name provided")
return
}
print("Hello, \(n)")
}
// Nil coalescing
let display = name ?? "Anonymous"
// Forced unwrap (risky)
let forced = name! // crash if nil
Q4. What is the difference between struct and class in Swift? Medium
| Feature | struct | class |
|---|---|---|
| Type | Value type | Reference type |
| Inheritance | No | Yes |
| ARC | No | Yes |
| Mutability | Methods must be mutating | Methods can mutate freely |
| Copy behavior | Deep copy on assignment | Shared reference |
struct Point { var x, y: Int }
var p1 = Point(x: 1, y: 2)
var p2 = p1 // COPY
p2.x = 99
print(p1.x) // 1 - unaffected
class Node { var value: Int; init(_ v: Int) { value = v } }
let n1 = Node(1)
let n2 = n1 // SAME reference
n2.value = 99
print(n1.value) // 99 - affected
Q5. What are enumerations in Swift and what makes them powerful? Medium
// Basic enum
enum Direction { case north, south, east, west }
// Enum with associated values
enum Result<T> {
case success(T)
case failure(Error)
}
// Enum with raw values
enum HTTPStatus: Int {
case ok = 200
case notFound = 404
case serverError = 500
}
let status = HTTPStatus(rawValue: 404) // Optional<HTTPStatus>
// Pattern matching with switch
func handle(result: Result<String>) {
switch result {
case .success(let data): print("Got: \(data)")
case .failure(let err): print("Error: \(err)")
}
}
Q6. What is a guard statement? Easy
func processAge(_ age: Int?) {
guard let age = age else {
print("age is nil")
return // must exit scope
}
guard age >= 18 else {
print("must be 18+")
return
}
print("Access granted, age: \(age)")
}
guard is preferred over nested if let for early exits. It keeps the happy path at the main indentation level.
Q7. What is defer in Swift? Medium
func readFile(path: String) {
let handle = openFile(path)
defer { closeFile(handle) } // runs when function exits
if errorCondition {
return // defer still runs
}
// ... process file
} // defer runs here
// Multiple defers run in reverse order
func main() {
defer { print("last") }
defer { print("middle") }
defer { print("first") }
// prints: first, middle, last
}
Q8. What is type casting in Swift (as, as?, as!)? Medium
class Animal {}
class Dog: Animal { func bark() { print("Woof") } }
let animal: Animal = Dog()
// as? - conditional cast, returns Optional
if let dog = animal as? Dog {
dog.bark() // safe
}
// as! - forced cast, crashes if wrong type
let dog = animal as! Dog // crash if not Dog
// as - compile-time cast (upcasting, always safe)
let a: Animal = Dog() as Animal
Q9. What is the difference between Any, AnyObject, and generics? Medium
// Any: any type (value or reference)
var mixed: [Any] = [1, "hello", 3.14, Dog()]
// AnyObject: any class instance (reference types only)
var objects: [AnyObject] = [Dog(), Cat()]
// Generics: type-safe, resolved at compile time
func identity<T>(_ value: T) -> T { return value }
let n = identity(42) // T inferred as Int
let s = identity("hello") // T inferred as String
Prefer generics over Any for type safety.
Q10. What are property observers? Medium
class Temperature {
var celsius: Double = 0 {
willSet {
print("About to change from \(celsius) to \(newValue)")
}
didSet {
print("Changed from \(oldValue) to \(celsius)")
if celsius < -273.15 {
celsius = oldValue // revert invalid value
}
}
}
}
Q11. What are computed properties? Medium
struct Circle {
var radius: Double
var area: Double { // computed get
return .pi * radius * radius
}
var diameter: Double {
get { return radius * 2 }
set { radius = newValue / 2 }
}
}
var c = Circle(radius: 5)
print(c.area) // 78.54
c.diameter = 20 // sets radius to 10
Q12. Predict the output: Easy
var x = 10
let closure = { print(x) } // captures x
x = 20
closure()
Output: 20
Explanation: Swift closures capture references to variables by default (not their current value). When closure is called, x is already 20.
OOP and Protocols
Q13. What are protocols in Swift? Medium
protocol Drawable {
var color: String { get }
func draw()
}
struct Circle: Drawable {
var color: String
func draw() { print("Drawing \(color) circle") }
}
struct Square: Drawable {
var color: String
func draw() { print("Drawing \(color) square") }
}
func render(shape: Drawable) { shape.draw() }
render(Circle(color: "red"))
render(Square(color: "blue"))
Q14. What are protocol extensions? Advanced
protocol Greetable {
var name: String { get }
func greet() -> String
}
// Default implementation via extension
extension Greetable {
func greet() -> String { return "Hello, \(name)!" }
}
struct Person: Greetable { var name: String }
// Person gets greet() for free, can override if needed
print(Person(name: "Aditya").greet()) // Hello, Aditya!
Q15. What is the difference between a protocol and an abstract class? Medium
| Feature | Protocol | Abstract class |
|---|---|---|
| Adoption | Multiple protocols possible | Single inheritance |
| Value types | Can adopt protocols | structs/enums can't inherit |
| Default impl | Via extensions | Yes |
| Stored properties | No (computed only) | Yes |
Q16. What is Codable (Encodable + Decodable)? Medium
struct User: Codable {
let name: String
let age: Int
let email: String
}
// Encode to JSON
let user = User(name: "Aditya", age: 25, email: "[email protected]")
let data = try JSONEncoder().encode(user)
let json = String(data: data, encoding: .utf8)!
// {"name":"Aditya","age":25,"email":"[email protected]"}
// Decode from JSON
let decoded = try JSONDecoder().decode(User.self, from: data)
print(decoded.name) // Aditya
Q17. What are generics in Swift? Medium
struct Stack<Element> {
private var items: [Element] = []
mutating func push(_ item: Element) { items.append(item) }
mutating func pop() -> Element? { items.popLast() }
var top: Element? { items.last }
}
var intStack = Stack<Int>()
intStack.push(1)
intStack.push(2)
print(intStack.pop()!) // 2
// Protocol constraint
func findMax<T: Comparable>(_ arr: [T]) -> T? {
return arr.max()
}
Q18. What is @discardableResult? Easy
@discardableResult
func saveFile(_ data: Data) -> Bool {
// ... write file
return true
}
saveFile(data) // no warning
let ok = saveFile(data) // also fine
Without @discardableResult, ignoring a return value produces a compiler warning.
Q19. What are subscripts? Medium
struct Matrix {
var data: [[Double]]
subscript(row: Int, col: Int) -> Double {
get { data[row][col] }
set { data[row][col] = newValue }
}
}
var m = Matrix(data: [[1, 2], [3, 4]])
print(m[0, 1]) // 2
m[1, 0] = 99
Q20. What is mutating in Swift structs? Medium
struct Counter {
var count = 0
mutating func increment() { // must be marked mutating
count += 1
}
}
var c = Counter()
c.increment()
// let c2 = Counter()
// c2.increment() // compile error - c2 is let
Value-type methods that modify self must be mutating. Class methods can always mutate.
Q21. What is final in Swift? Easy
final class Singleton { // cannot be subclassed
static let shared = Singleton()
private init() {}
}
class Base {
final func doWork() { } // method cannot be overridden
var value = 0
}
final improves performance (enables devirtualization) and prevents unintended subclassing.
Q22. Predict the output: value vs reference. Medium
struct Point { var x: Int }
class Box { var value: Int; init(_ v: Int) { value = v } }
var p1 = Point(x: 1)
var p2 = p1
p2.x = 99
print(p1.x) // ?
var b1 = Box(1)
var b2 = b1
b2.value = 99
print(b1.value) // ?
Output: 1, then 99
Explanation: Point is a struct (value type) - p2 is an independent copy. Box is a class (reference type) - b2 and b1 point to the same object.
Memory Management: ARC
Q23. What is ARC (Automatic Reference Counting)? Medium
class Person {
let name: String
init(name: String) {
self.name = name
print("\(name) allocated")
}
deinit { print("\(name) deallocated") }
}
var ref1: Person? = Person(name: "Aditya") // count: 1
var ref2 = ref1 // count: 2
ref1 = nil // count: 1
ref2 = nil // count: 0 → "Aditya deallocated"
Q24. What is a retain cycle and how do you prevent it? Medium
// RETAIN CYCLE
class Owner {
var pet: Pet?
}
class Pet {
var owner: Owner? // strong reference back - cycle!
}
// FIX: use weak reference
class Pet {
weak var owner: Owner? // won't prevent deallocation
}
Q25. What is the difference between weak and unowned? Medium
| Feature | weak | unowned |
|---|---|---|
| Optional | Yes (T?) | No (T) |
| Behavior if nil | Safe (Optional) | Crash (like !) |
| Use case | When reference may become nil | When reference has same/longer lifetime |
class View {
var delegate: ViewDelegate? // strong
}
protocol ViewDelegate: AnyObject {}
class Controller: ViewDelegate {
lazy var view: View = {
let v = View()
v.delegate = self
return v
}()
// In view's closure, use weak self if Controller can be deallocated
func setup() {
view.onTap = { [weak self] in
self?.handleTap()
}
}
}
Q26. What is [weak self] in closures? Medium
class ViewController {
var timer: Timer?
func startTimer() {
// Without [weak self]: ViewController is retained by timer closure
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
guard let self = self else { return }
self.updateUI()
}
}
}
Without [weak self], the closure retains self, creating a cycle if self also retains the closure.
Q27. What is deinit in Swift? Easy
class DatabaseConnection {
init() { print("Connection opened") }
deinit {
print("Connection closed")
// cleanup resources
}
}
deinit is called when a class instance is deallocated. It has no parameters and cannot be called directly.
Q28. What is autoreleasepool? Advanced
for _ in 0..<1_000_000 {
autoreleasepool {
let image = loadLargeImage() // temporary objects
process(image)
} // image released here, not at end of loop
}
In tight loops creating many temporary objects, autoreleasepool prevents memory spikes by releasing objects at the pool boundary.
Q29. Predict the output: retain count. Advanced
class Obj {
deinit { print("deallocated") }
}
var a: Obj? = Obj()
var b = a
a = nil
print("after a = nil")
b = nil
print("after b = nil")
Output:
after a = nil
deallocated
after b = nil
Explanation: When a = nil, count drops from 2 to 1 (b still holds it). Only when b = nil does count reach 0 and deallocation occurs.
Closures and Functional Programming
Q30. What is a closure in Swift? Medium
// Closure expression
let square: (Int) -> Int = { n in n * n }
// Shorthand argument names
let cube: (Int) -> Int = { $0 * $0 * $0 }
// Trailing closure syntax
let nums = [3, 1, 4, 1, 5]
let sorted = nums.sorted { $0 < $1 } // trailing closure
let sorted2 = nums.sorted(by: <) // even shorter
Q31. What is map, filter, reduce in Swift? Medium
let nums = [1, 2, 3, 4, 5]
let doubled = nums.map { $0 * 2 } // [2, 4, 6, 8, 10]
let evens = nums.filter { $0 % 2 == 0 } // [2, 4]
let sum = nums.reduce(0, +) // 15
let product = nums.reduce(1, *) // 120
// Chaining
let result = nums
.filter { $0 > 2 }
.map { $0 * $0 }
.reduce(0, +)
// filter: [3,4,5], map: [9,16,25], reduce: 50
Q32. What is compactMap? Medium
let strings = ["1", "two", "3", "four", "5"]
let ints = strings.compactMap { Int($0) }
// [1, 3, 5] - nil values from failed conversions are removed
// Also removes optionals from array
let maybes: [Int?] = [1, nil, 3, nil, 5]
let real = maybes.compactMap { $0 } // [1, 3, 5]
Q33. What is flatMap for sequences? Medium
let nested = [[1, 2, 3], [4, 5], [6]]
let flat = nested.flatMap { $0 } // [1, 2, 3, 4, 5, 6]
// flatMap on Optional (maps and flattens)
let numbers: [String?] = ["1", nil, "3"]
let parsed = numbers.flatMap { $0.flatMap(Int.init) } // [1, 3]
Q34. What is @escaping? Advanced
// Non-escaping (default): closure runs within function lifetime
func synchronous(completion: () -> Void) {
completion()
}
// @escaping: closure may outlive the function
func asynchronous(completion: @escaping () -> Void) {
DispatchQueue.global().async {
// ... work
completion() // called after function returns
}
}
// @escaping requires explicit self capture
class Obj {
func loadData(completion: @escaping () -> Void) {
DispatchQueue.main.async { [weak self] in
self?.update()
completion()
}
}
}
Q35. What is @autoclosure? Medium
func logIfDebug(_ message: @autoclosure () -> String) {
if isDebug {
print(message()) // expression only evaluated if isDebug
}
}
logIfDebug("expensive \(computeDescription())")
// computeDescription() only called if isDebug is true
@autoclosure wraps an expression in a closure automatically. Used in assert, precondition, and lazy evaluation.
Q36. Predict the output: capturing semantics. Advanced
var funcs: [() -> Int] = []
for i in 0..<3 {
funcs.append({ i })
}
funcs.forEach { print($0()) }
Output:
0
1
2
Explanation: In Swift's for loop, i is a let constant rebound each iteration. Each closure captures a different binding of i, unlike some other languages.
Concurrency
Q37. What is async/await in Swift? Medium
// Async function declaration
func fetchUser(id: Int) async throws -> User {
let url = URL(string: "https://api.example.com/users/\(id)")!
let (data, _) = try await URLSession.shared.data(from: url)
return try JSONDecoder().decode(User.self, from: data)
}
// Calling async functions
func loadProfile() async {
do {
let user = try await fetchUser(id: 42)
print(user.name)
} catch {
print("Error: \(error)")
}
}
Q38. What are Swift actors? Advanced
actor BankAccount {
private var balance: Double
init(balance: Double) { self.balance = balance }
func deposit(_ amount: Double) { balance += amount }
func withdraw(_ amount: Double) -> Bool {
guard balance >= amount else { return false }
balance -= amount
return true
}
var currentBalance: Double { balance }
}
let account = BankAccount(balance: 1000)
await account.deposit(500)
let ok = await account.withdraw(200)
Q39. What is async let? Advanced
// Sequential (slow)
let user = await fetchUser(id: 1)
let orders = await fetchOrders(userId: 1)
// Concurrent with async let
async let user = fetchUser(id: 1)
async let orders = fetchOrders(userId: 1)
// Both started immediately, results awaited together
let (u, o) = await (user, orders)
Q40. What is TaskGroup? Advanced
func fetchAllUsers(ids: [Int]) async -> [User] {
await withTaskGroup(of: User?.self) { group in
for id in ids {
group.addTask { try? await fetchUser(id: id) }
}
var users: [User] = []
for await user in group {
if let u = user { users.append(u) }
}
return users
}
}
Q41. What was GCD (Grand Central Dispatch)? Medium
// Pre-async/await (still common in older code)
DispatchQueue.global(qos: .userInitiated).async {
let data = fetchHeavyData()
DispatchQueue.main.async {
self.updateUI(data) // back on main thread
}
}
// DispatchGroup for parallel work
let group = DispatchGroup()
group.enter()
fetchA { group.leave() }
group.enter()
fetchB { group.leave() }
group.notify(queue: .main) { handleBothDone() }
Q42. What is @MainActor? Medium
@MainActor
class ViewModel: ObservableObject {
@Published var title = ""
func loadData() async {
let text = await fetchText() // runs on any thread
title = text // @MainActor guarantees main thread
}
}
Q43. What is structured concurrency in Swift? Advanced
Q44. Predict the output: Advanced
Task {
async let a = { () async -> Int in
try? await Task.sleep(nanoseconds: 100_000_000)
return 1
}()
async let b = { () async -> Int in
return 2
}()
print(await a + b)
}
Output: 3
Explanation: Both tasks start concurrently. b finishes immediately, a after ~100ms. Sum is 3.
SwiftUI and Combine
Q45. What is SwiftUI? How does it differ from UIKit? Medium
| Feature | SwiftUI | UIKit |
|---|---|---|
| Paradigm | Declarative | Imperative |
| Platform | All Apple platforms | iOS/tvOS |
| State management | @State, @Binding, @ObservedObject | Delegate, notification, KVO |
| Previews | Live canvas previews | Build and run |
| Maturity | Newer (iOS 13+) | Established (iOS 2+) |
struct ContentView: View {
@State private var count = 0
var body: some View {
VStack {
Text("Count: \(count)")
Button("Increment") { count += 1 }
}
}
}
Q46. What are property wrappers @State, @Binding, @ObservedObject? Medium
// @State: local mutable state
@State var name = ""
// @Binding: two-way connection to parent state
struct TextField: View {
@Binding var text: String
}
// @ObservedObject: external observable class
class ViewModel: ObservableObject {
@Published var users: [User] = []
}
struct UserList: View {
@ObservedObject var vm: ViewModel
}
// @StateObject: like @ObservedObject but owned by the view
struct RootView: View {
@StateObject var vm = ViewModel()
}
Q47. What is some View? Advanced
// Without some: complex nested type exposed
// func body -> VStack<TupleView<(Text, Button<Text>)>>
// With some: clean, hides implementation detail
var body: some View {
VStack {
Text("Hello")
Button("Tap me") {}
}
}
Q48. What is Combine? Advanced
// Publisher: URLSession data task
URLSession.shared
.dataTaskPublisher(for: URL(string: "https://api.example.com")!)
.map(\.data)
.decode(type: Response.self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.sink(
receiveCompletion: { print("Completed: \($0)") },
receiveValue: { print("Received: \($0)") }
)
.store(in: &cancellables)
Q49. What is @EnvironmentObject? Medium
class AppSettings: ObservableObject {
@Published var darkMode = false
}
// Inject at root
ContentView().environmentObject(AppSettings())
// Access anywhere in view hierarchy
struct SettingsView: View {
@EnvironmentObject var settings: AppSettings
var body: some View {
Toggle("Dark Mode", isOn: $settings.darkMode)
}
}
Q50. What is the Identifiable protocol? Easy
struct Todo: Identifiable {
let id = UUID()
var title: String
var done = false
}
// Required for ForEach in SwiftUI
ForEach(todos) { todo in
Text(todo.title)
}
Identifiable requires an id property and tells SwiftUI how to uniquely track list items for efficient updates.
Mock Interview: 5 Questions
- Explain the difference between
weakandunownedwith a memory diagram example. - Given a list of
User?optionals, write a functional chain to get valid email addresses in uppercase. - Implement a thread-safe cache using an actor.
- When would you choose
structoverclass? Give three concrete examples. - Rewrite this GCD callback-based network call using async/await.
FAQ
Q: Do I need UIKit knowledge if I know SwiftUI? A: Yes. Most production apps have UIKit code, and some UIKit integrations (UIViewRepresentable, UIViewControllerRepresentable) are essential for using UIKit components in SwiftUI. Interviewers usually ask about both.
Q: Is Swift useful outside Apple platforms? A: Swift is open source and runs on Linux. Server-side Swift (Vapor, Hummingbird) has a niche community. But for job market impact, Swift means Apple platform development.
Q: How important is Combine vs async/await?
A: Async/await is Apple's preferred approach for new code. Combine is still important for reactive bindings in SwiftUI (@Published, sink). Know both patterns.
Related reading: Flutter Interview Questions 2026 | React Native Interview Questions 2026 | Kotlin Interview Questions 2026 | Dart Interview Questions 2026
Methodology applied to this articlelast verified 8 Jun 2026
- No fabricated salary numbers or success rates. If we quote a range, it's sourced.
- No noun-substituted templates. This article was not generated by swapping company names in a stock prompt.
- No paid placements, sponsored coaching links, or affiliate-shilled course pushes.
topic cluster
More resources in Interview Questions
Use the category hub to browse similar questions, exam patterns, salary guides, and preparation resources related to this topic.
paid contributor programme
Sat this this year? Share your story, earn ₹500.
First-person experience reports help future candidates prep smarter. We pay verified contributors ₹500 via UPI per accepted story with byline.
Submit your story →ready to practice?
Take a free timed mock test
Put what you learned into practice. Our mock tests match the 2026 pattern with timer, navigator, reveal, and score breakdown. No signup.