Welcome back to the second installment of our “Basic iOS InterView question” series. In the first part, we covered some foundational concepts that every aspiring iOS developer should be familiar with. As we continue our journey, this part will delve deeper into the core aspects of iOS development. Whether you’re brushing up on your knowledge or preparing for an upcoming interview, these questions and explanations will help solidify your understanding of essential iOS principles. Let’s dive in and explore the next set of topics that are crucial for acing your basic iOS interview.
26. What is Property Observer?
In Swift, a property observer is a feature that allows you to observe and respond to changes in the value of a property. Property observers are available for stored properties, which are properties that store a value.
There are two types of property observers in Swift: willSet
and didSet
.
willSet
is called just before the value of the property is about to change. It provides you with the new value as a parameter, and you can use it to perform any necessary operations before the value is updated. Here is an example:
var myProperty: Int = 0 {
willSet(newPropertyValue) {
print("The new value of myProperty is \(newPropertyValue)")
}
}
didSet
is called immediately after the value of the property has been updated. It provides you with the old value of the property as a parameter, and you can use it to perform any necessary operations after the value has been updated. Here is an example:
var myProperty: Int = 0 {
didSet(oldPropertyValue) {
print("The old value of myProperty was \(oldPropertyValue)")
}
}
Property observers can be used to perform various tasks when the value of a property changes, such as updating a user interface element, updating a related property, or triggering a network request. They are a powerful tool for building reactive and dynamic applications in Swift.
27. What is a designated initializer?
In Swift, a designated initializer is a special initializer that is responsible for initializing all of the properties of a class, and ensuring that the object is fully initialized before it can be used. A designated initializer is required for every class in Swift.
A designated initializer is defined using the init
keyword, and it must call the superclass’s designated initializer using super.init
to ensure that all of the properties inherited from the superclass are initialized. It can then go on to initialize the properties specific to the subclass.
Here is an example of a class with a designated initializer:
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
class Student: Person {
var studentId: Int
init(name: String, age: Int, studentId: Int) {
self.studentId = studentId
super.init(name: name, age: age)
}
}
In this example, the Person
class defines a designated initializer that initializes the name
and age
properties. The Student
class inherits from Person
and adds a new property called studentId
. It defines a designated initializer that initializes the studentId
property and then calls the superclass’s designated initializer using super.init(name: name, age: age)
.
By ensuring that every class has a designated initializer, Swift helps ensure that objects are initialized consistently and safely, making it easier to write bug-free code.
28. What is a convenience initializer?
In Swift, there are two types of initializers: designated initializers and convenience initializers. The difference between the two is in their level of responsibility for initializing a class’s properties.
A convenience initializer is a secondary initializer that provides a shortcut for creating an instance of a class. It can only call a designated initializer in the same class, either directly or indirectly through another convenience initializer. A convenience initializer cannot initialize properties that are not initialized by the designated initializer.
Here is an example of a class with both a designated initializer and a convenience initializer:
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
convenience init(name: String) {
self.init(name: name, age: 0)
}
}
In this example, the Person
class has a designated initializer that initializes the name
and age
properties. It also has a convenience initializer that takes only a name
parameter and sets the age
property to 0. The convenience initializer calls the designated initializer using self.init(name: name, age: 0)
.
Here is an example of a class with multiple designated initializers:
class Rectangle {
var width: Double
var height: Double
init(width: Double, height: Double) {
self.width = width
self.height = height
}
convenience init(squareLength: Double) {
self.init(width: squareLength, height: squareLength)
}
}
In this example, the Rectangle
class has two designated initializers: one that takes a width
and height
parameter, and one that takes only a squareLength
parameter and initializes both width
and height
to that value. The convenience initializer calls the first designated initializer using self.init(width: squareLength, height: squareLength)
.
29. What is SceneDelegate?
The SceneDelegate
is a class introduced in iOS 13 as part of the new multi-window scene management system in UIKit. It works alongside the AppDelegate
to manage the lifecycle of individual scenes (or windows) in your app. A scene represents an instance of your app’s user interface, and the SceneDelegate
handles the lifecycle events related to that scene.
Key Responsibilities of SceneDelegate:
- Scene Lifecycle Management:
- The
SceneDelegate
manages the lifecycle of a scene, including when it is created, enters the foreground, goes to the background, and is destroyed. - Lifecycle methods include
scene(_:willConnectTo:options:)
,sceneDidBecomeActive(_:)
,sceneWillResignActive(_:)
,sceneWillEnterForeground(_:)
, andsceneDidEnterBackground(_:)
.
- The
- Multi-Window Support:
- With iOS 13 and later, apps can support multiple windows (scenes) on devices like iPad. Each window is represented by a separate scene, and each scene has its own
SceneDelegate
. - The
SceneDelegate
allows developers to manage each window’s state independently.
- With iOS 13 and later, apps can support multiple windows (scenes) on devices like iPad. Each window is represented by a separate scene, and each scene has its own
- State Restoration:
- The
SceneDelegate
helps in restoring the state of a scene if the system terminates it to reclaim resources and then relaunches it later. - Developers can save and restore the scene’s state through methods like
scene(_:willConnectTo:options:)
andscene(_:didUpdate:)
.
- The
- User Interface Management:
- The
SceneDelegate
is where you typically set up the root view controller of the scene’s window. - Unlike
AppDelegate
, which managed the app’s single window in older iOS versions,SceneDelegate
now handles the window management at the scene level.
- The
30. What is the iOS application lifecycle?
The application life cycle refers to the various states and transitions that an application goes through from its launch to termination. While the specifics can vary depending on the platform and framework, here is a general overview of the application life cycle in the context of mobile app development:
- Not Running: The application is not in memory or has been terminated by the user or the operating system.
- Launching: The application is being launched but not yet ready to run.
- Inactive: The application is running in the foreground but not receiving any events or user interactions. This state occurs briefly before transitioning to the active state.
- Active: The application runs in the foreground and receives events and user interactions. This is the state where the main functionality of the app is active.
- Background: The application has been moved to the background due to the user switching to another app or an incoming call. While in the background, the app can continue to execute code and perform certain tasks, such as playing audio or updating location information.
- Suspended: The application is in the background, but its execution has been paused by the operating system. It remains in memory but does not actively run any code. The operating system may remove suspended apps from memory if system resources become scarce.
- Terminated: The application has been completely shut down either by the user or the operating system. Any unsaved data or state is lost.
Throughout the life cycle, the application can transition between these states based on user interactions, system events, and other factors. Developers can handle these state transitions and implement appropriate logic to save and restore application state, manage resources, and respond to events.
31. What is the lifecycle of the view controller?
The view controller life cycle refers to the series of events and methods that are called during the lifespan of a view controller in an iOS app. It provides developers with hooks to perform specific tasks at different stages of the view controller’s existence. Here is a typical view controller life cycle in iOS:
- Initialization: This is the initial stage where the view controller object is created. The
init
method is called during this phase, and you can perform any necessary setup tasks. - Loading the View: Once the view controller is initialized, the system loads the view associated with the view controller from a nib file or creates it programmatically. The
loadView
method is called in this phase, where you can create and configure the view hierarchy manually if needed. - ViewDidLoad: After the view is loaded, the
viewDidLoad
method is called. This is a good place to perform any additional setup tasks related to the view, such as initializing data sources, setting up UI elements, or fetching initial data. - ViewWillAppear and ViewDidAppear: These methods are called just before the view is about to appear on the screen (
viewWillAppear
) and immediately after it appears (viewDidAppear
). You can use these methods to perform tasks such as refreshing data, starting animations, or updating the UI based on the current state. - ViewWillDisappear and ViewDidDisappear: These methods are called when the view is about to disappear from the screen (
viewWillDisappear
) and after it has disappeared (viewDidDisappear
). Here, you can clean up resources, stop animations, or save any necessary state. - Memory Warnings: If the system receives a memory warning, it may request view controllers to release any unnecessary resources to free up memory. The
didReceiveMemoryWarning
method is called in such cases, allowing you to release non-essential data or objects. - Deinitialization: When a view controller is no longer needed, it is deallocated from memory. The
deinit
method is called, and you can perform any final cleanup tasks before the view controller is removed.
Understanding the view controller life cycle is crucial for managing the state, updating the UI, handling data, and managing resources effectively in an iOS app. It allows developers to respond appropriately to different stages of the view controller’s life and provide a smooth user experience.
32. What is String Interpolation?
String interpolation is a feature in programming languages that allows you to insert variables, expressions, or values directly into a string. It provides a convenient way to combine strings with other data types without having to manually concatenate or format them.
In Swift, string interpolation is accomplished by using the \()
syntax within a string literal. Anything placed within the parentheses \(
and )
will be evaluated and inserted into the string at that location. The expression inside the parentheses can be a variable, a constant, or any other valid expression that can be converted to a string.
Here’s an example in Swift to illustrate string interpolation:
let name = "Alice"
let age = 30
let message = "My name is \(name) and I am \(age) years old."
print(message)
In this example, the variables name
and age
are inserted into the message
string using string interpolation. The values of name
and age
are automatically converted to strings and substituted into the respective locations within the string. When the message
is printed, it will display: “My name is Alice and I am 30 years old.”
String interpolation simplifies the process of building strings that incorporate dynamic or variable data. It improves code readability, eliminates the need for manual string concatenation, and provides a more expressive and concise way to include values within strings.
33. How to enter the string in multiple lines?
To enter a string in multiple lines in Swift, you can use multiline string literals. Multiline string literals allow you to write a string that spans multiple lines while preserving the line breaks and formatting.
There are two types of multiline string literals in Swift:
- Double quotation marks with three leading and trailing double quotation marks (
"""
): This type of multiline string literal can include line breaks and preserve indentation. Here’s an example:
let multilineString = """
This is a string
that spans
multiple lines.
"""
In this example, the multilineString
contains a string that spans multiple lines while preserving the line breaks and the indentation.
- Triple quotation marks (
"""
): This type of multiline string literal can also include line breaks but does not preserve indentation. Here’s an example:
let multilineString = """
This is a string
that spans
multiple lines.
"""
In this example, the multilineString
contains a string that spans multiple lines without preserving the indentation.
Both types of multiline string literals can be used to enter strings that span multiple lines. Choose the appropriate type based on whether you need to preserve the indentation or not.
It’s important to note that the leading indentation on each line is automatically removed from multiline string literals. If you want to maintain specific indentation levels, you can use the trimmingCharacters(in:)
method to remove leading whitespace characters as needed.
34. What is Defer Statement? Where to use?
defer
is a statement in Swift that allows you to specify a block of code to be executed when the current scope is exited, regardless of whether the scope is exited normally or due to an error. This can be useful for cleaning up resources or performing tasks that should always be done before exiting a scope.
The syntax for use defer
is simple. You simply write the keyword defer
followed by a block of code enclosed in braces. The block of code will be executed when the current scope is exited:
func myFunction() {
defer {
print("This will be printed last")
}
print("This will be printed first")
}
In this example, the defer
statement specifies a block of code that will be executed when the myFunction()
scope is exited, regardless of whether it is exited normally or due to an error. The block of code simply prints a message to the console.
When you call myFunction()
, the following output will be printed to the console:
This will be printed first
This will be printed last
As you can see, the defer
block is executed after the main body of the function has been completed but before the function returns.
You can use defer
statements to clean up resources such as closing files or releasing memory, as well as for performing other tasks that should always be done before exiting a scope, such as logging or error reporting.
It’s worth noting that defer
statements are executed in reverse order from how they are declared. So if you have multiple defer
statements, the last one declared will be executed first, followed by the second last, and so on.
For a deeper dive into app defer statement in Swift, check out our detailed guide here.
35. What is the Difference between KVC and KVO?
KVO and KVC are two concepts in iOS development that deal with observing and manipulating the properties of objects.
KVO stands for Key-Value Observing and is a mechanism that allows you to observe changes to a property of an object. When the property changes, a notification is sent, and an observer can take appropriate action. KVO is typically used in situations where you want to be notified when a property of an object changes and responds to that change.
KVC, on the other hand, stands for Key-Value Coding and is a mechanism for accessing an object’s properties using strings to specify the properties, rather than using dot notation. KVC allows you to access an object’s properties dynamically, at runtime, rather than having to know the property names at compile time. This can be useful in situations where you need to access properties of an object that you don’t know at compile time.
In summary, KVO is used to observe changes to properties, while KVC is used to access properties dynamically. Both KVO and KVC can be used together to build more dynamic and flexible systems in iOS development.
36. What is the difference between selector and function?
In Swift, selectors and functions are related concepts but serve different purposes.
Here are the key points that summarize the difference between a selector and a function in Swift:
Functions:
- Definition: A block of code that performs a specific task.
- Usage: Directly invoked in code for executing specific behavior.
- Compile-Time Resolution: Functions are resolved at compile-time, meaning the compiler knows which function is being called.
- Syntax: Defined using the
func
keyword.
Selectors:
- Definition: An indirect reference to the name of a method, used primarily in Objective-C and Swift interoperability.
- Usage: Used to specify a method to be called later, often in response to an event, particularly with UI components (e.g., button taps).
- Runtime Resolution: Selectors are resolved at runtime, meaning the method is dynamically looked up when needed.
- Syntax: Created using the
#selector
syntax. - Context: Commonly used in scenarios like target-action patterns and
NotificationCenter
.
37. What is the difference between a Universal app and a Targeted app?
In iOS development, a Universal app and a Targeted app refer to two different approaches to building apps for multiple devices.
A Universal app is a single app that is designed to run on all iOS devices, including iPhones, iPads, and iPod touch. The app is built with a single set of code and resources that can adapt to different screen sizes and resolutions. A Universal app can take advantage of different features and capabilities of each device, such as the larger screen of an iPad or the camera of an iPhone.
A Targeted app, on the other hand, is an app that is designed specifically for a particular device or platform. For example, an iPhone app may be designed specifically for the iPhone’s screen size and resolution, and may not work properly on an iPad or other devices. A Targeted app may have different features and user interfaces tailored to the specific device or platform it is designed for.
In summary, a Universal app is designed to run on all iOS devices with a single set of code and resources, while a Targeted app is designed specifically for a particular device or platform. Universal apps are more flexible and can reach a wider audience, while targeted apps can provide a more optimized and tailored experience for specific devices or platforms.
38 What is the difference between Objective C const vs Swift let?
In Objective-C, const
is a keyword used to define constant values, while in Swift, let
is used for the same purpose. Here are some differences between the two:
- Syntax: In Objective-C, you define a constant using the
const
keyword before the variable name, while in Swift, you use thelet
keyword.
const int myConstant = 5;
let myConstant = 5
- Immutability: In both Objective-C and Swift, constants are immutable, meaning their value cannot be changed once they are initialized. In Objective-C, however, a pointer to a constant value can be re-assigned to point to another constant value.
const int *p = &myConstant;
p = &newConstant; // re-assignment is allowed
In Swift, let
constants are completely immutable and cannot be re-assigned to another value or object.
let myConstant = 5
myConstant = 10 // error: cannot assign to 'let' value 'myConstant'
- Scope: In Objective-C, a
const
can be declared either globally or locally within a method or function. In Swift,let
constants can be declared globally, within a class, struct, or enum, or locally within a method, function, or closure. - Type Inference: In Swift,
let
constants can be assigned a value without specifying their type, as the compiler can infer the type from the assigned value. In Objective-C, however, the type of a constant must be explicitly defined.
let myConstant = 5 // type inferred as Int
const int myConstant = 5; // type explicitly defined as int
Overall, while there are some syntactic and semantic differences between the two, the purpose of both const
in Objective-C and let
in Swift is to define a value that cannot be changed once it has been initialized.
39. What is mutating? When to use?
In Swift, the mutating
keyword is used in the context of value types, such as structs and enums, to indicate that a method will modify (mutate) the properties of the instance it is called on. Normally, methods on value types cannot modify the instance itself because value types are immutable by default. However, by marking a method as mutating
, you explicitly allow it to modify the properties of the instance.
When to Use mutating:
- Modifying Properties: You should use the
mutating
keyword when you need a method within a struct or enum to modify the properties of that instance. Withoutmutating
, you wouldn’t be able to change the values of the instance’s properties within the method. - Self-Reassignment: If the method needs to reassign
self
to a new instance, that method must be marked asmutating
.
Example of a Mutating Method:
Consider a struct
that represents a simple counter:
struct Counter {
var count = 0
mutating func increment() {
count += 1
}
mutating func reset() {
count = 0
}
}
var myCounter = Counter()
myCounter.increment() // count is now 1
myCounter.reset() // count is now 0
40. What is the Protocol?
In Swift, a protocol is a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. Protocols can then be adopted by classes, structures, or enumerations to provide an actual implementation of those requirements.
Key Features of Protocols:
- Method and Property Requirements: A protocol can specify methods and properties that the adopting type must implement. These methods and properties can be either instance-based or type-based (i.e., static).
- Default Implementations: Using protocol extensions, you can provide default implementations for the methods and properties required by a protocol.
- Multiple Inheritance: A type can conform to multiple protocols, allowing it to inherit multiple sets of behaviors.
- Protocol Inheritance: One protocol can inherit the requirements of another protocol, adding its own requirements on top.
Example of a Protocol:
protocol Drivable {
var hasWheels: Bool { get }
func startEngine()
func drive()
}
41. What is Precedence Group?
In Swift, a precedence group defines the order in which operators are evaluated in expressions that contain multiple operators. It also determines how operators of the same precedence group are grouped (associativity) when there are multiple operators with the same precedence level.
42. What is inout in swift? How and why do you use it?
In Swift, the inout
keyword is used to indicate that a function parameter can be modified within the function, and those modifications will persist outside the function. Essentially, it allows you to pass a parameter by reference rather than by value.
Example of Using inout:
Here’s a simple example of a function that swaps the values of two integers:
func swapValues(_ a: inout Int, _ b: inout Int) {
let temp = a
a = b
b = temp
}
var x = 10
var y = 20
swapValues(&x, &y)
print("x: \(x), y: \(y)") // Output: x: 20, y: 10
43. How to use Interval matching in Switch?
In Swift, you can use interval matching within a switch
statement to match a value against a range of values. This is particularly useful when you want to categorize or handle a value based on whether it falls within a specific range.
Example of Interval Matching in a Switch Statement
Let’s say you want to classify a person’s age into different categories (child, teenager, adult, etc.). Here’s how you can do it using interval matching:
let age = 25
switch age {
case 0...12:
print("Child")
case 13...19:
print("Teenager")
case 20...64:
print("Adult")
case 65...:
print("Senior")
default:
print("Invalid age")
}
44. What is closure?
In Swift, a closure is a self-contained block of code that can be passed around and used in your code. Closures can capture and store references to variables and constants from the context in which they are defined, known as capturing values. This makes closures powerful and flexible in handling tasks, especially for tasks like event handling, completion handling, and callbacks.
Key Features of Closures:
- Anonymous Functions: Closures are often referred to as anonymous functions because they don’t have to have a name.
- Capturing Values: Closures can capture and store references to variables and constants from the surrounding context, making them useful for things like completion handlers where you need to maintain state.
- First-Class Citizens: Closures can be assigned to variables, passed as arguments to functions, and returned from functions.
- Inline: Closures are often defined inline, making them a concise way to implement functionality.
- Syntax: Swift closures have a clean and concise syntax, which can be simplified further with syntax sugar for single-expression closures, implicit returns, shorthand argument names, etc.
45. What is difference between SceneDelegate and AppDelegate?
In Swift and iOS development, SceneDelegate
and AppDelegate
are two key components introduced by Apple to manage the lifecycle of an app, particularly with the introduction of multi-window support in iOS 13.
AppDelegate
The AppDelegate
is a class that has been a central part of iOS applications since the beginning. It handles high-level app lifecycle events and overall application-level configurations.
SceneDelegate
The SceneDelegate
was introduced in iOS 13 to support multi-window functionality on iPadOS and iOS, where an app can have multiple UI windows (or scenes). Each scene represents an instance of the app’s UI.
Key Differences Between AppDelegate and SceneDelegate:
- Scope:
AppDelegate
: Manages the app’s overall lifecycle and global events that apply to the entire app.SceneDelegate
: Manages the lifecycle of individual scenes (windows) within the app, supporting multi-window capabilities.
- Lifecycle Management:
AppDelegate
: Responsible for app-level lifecycle events such as launching, entering background, and termination.SceneDelegate
: Handles lifecycle events specific to each scene, like connecting, disconnecting, and scene-specific backgrounding.
- UI Responsibility:
AppDelegate
: In pre-iOS 13 apps, it was responsible for setting up the initial UI. In apps usingSceneDelegate
, this responsibility is shifted toSceneDelegate
.SceneDelegate
: Handles the setup and configuration of the UI for each scene.
- Multi-Window Support:
AppDelegate
: Not directly involved in multi-window support.SceneDelegate
: Essential for managing multiple windows (scenes) in iOS apps.
46. What is reuseIdentifier?
In iOS development, particularly when working with table views (UITableView
) or collection views (UICollectionView
), a reuseIdentifier
is a string identifier used to efficiently reuse cells within the view. This helps in optimizing memory usage and performance by avoiding the need to create new cells every time a cell is displayed.
Why is reuseIdentifier Important?
When a table view or collection view needs to display a new cell, it tries to dequeue a reusable cell with the specified reuseIdentifier
. If a reusable cell is available, it returns that cell; otherwise, it creates a new cell. This reuse mechanism significantly improves performance, especially when dealing with large datasets, because it reduces the overhead of creating and disposing of many cell objects.
47. What is the Notification Center?
The NotificationCenter
in Swift is a powerful mechanism that enables different parts of an app to communicate with each other by broadcasting and listening for events. It allows for a decoupled architecture, where objects can observe and respond to events without directly referencing each other.
How Does Notification Center Work?
- Broadcasting (Posting) Notifications: Any object can broadcast a notification by posting it to the
NotificationCenter
. This notification can carry data in the form of auserInfo
dictionary. - Observing Notifications: Objects that are interested in certain events can register themselves as observers for those notifications. When the notification is posted, the observer’s callback method is invoked.
48. What is Type Inference?
Type inference is a feature in Swift that allows the compiler to automatically deduce the type of a variable or constant based on the value assigned to it, without the need for explicit type annotations by the developer.
How Type Inference Works
When you declare a variable or constant and assign a value to it, Swift’s compiler analyzes the value to determine its type. This reduces the amount of code you need to write and makes the code more concise.
49. What is a delegate?
A delegate in Swift is a design pattern that allows one object to communicate or pass responsibility to another object in a loosely coupled way. It is commonly used to handle events, pass data, or manage tasks between two objects where one acts as the delegator and the other as the delegate.
How Does the Delegate Pattern Work?
The delegate pattern involves two main components:
- Delegator: This is the object that needs to delegate some of its responsibilities. It defines a protocol that outlines the methods the delegate must implement.
- Delegate: This is the object that takes on the responsibility of performing certain tasks. It conforms to the protocol defined by the delegator and implements the required methods.
50. What’s the difference between delegate and notification center?
Delegates and the Notification Center are both mechanisms in Swift for facilitating communication between objects, but they serve different purposes and are used in different scenarios.
Here are some key points that highlight the differences between a delegate and the Notification Center in Swift.
Delegates:
- One-to-One Communication: A delegate is a design pattern used for one-to-one communication between objects.
- Tight Coupling: The delegator (the object that sends messages) has a direct reference to the delegate (the object that receives messages), leading to a tighter coupling.
- Protocol-Based: Delegates rely on protocols to define the methods that the delegate must implement.
- Specific Use Cases: Ideal for scenarios where a specific object needs to handle events or tasks, such as handling user interactions in a view controller.
- Direct Communication: The delegator directly calls the delegate’s methods, making the communication straightforward and controlled.
- Implementation Complexity: Requires more setup, including defining a protocol and assigning a delegate.
Notification Center:
- One-to-Many or Many-to-Many Communication: The Notification Center allows for broadcasting messages to multiple observers (listeners).
- Loose Coupling: The sender and receivers are loosely coupled; the sender doesn’t know who is listening.
- No Protocol Required: Notifications do not require protocols; observers simply register to receive specific notifications.
- Broad Use Cases: Suitable for system-wide events or when multiple objects need to respond to the same event.
- Indirect Communication: Notifications are broadcasted, and any registered observer can respond, leading to more flexible communication.
- Ease of Use: Easier to implement with simple registration and handling of notifications.
Summary:
In this second part of our “Basic iOS Interview Questions” series, we explored additional key concepts that form the backbone of iOS development. From understanding memory management to navigating through Xcode’s features, these questions are designed to reinforce your foundational knowledge. Mastering these basics is crucial, as they serve as the building blocks for more advanced topics in iOS development. Stay tuned for the next part, where we’ll continue to build on these concepts and help you prepare for any iOS interview with confidence.