// 19 Essential Swift Interview Questions
Swift is a robust and interactive programming language developed by Apple Inc. for Linux, tvOS, watchOS, macOS, and iOS development. It is quick, secure, and welcoming to new programs, making it an excellent way to create software.
Swift, an alternative to Objective-C with additional object-oriented features, is the most widely used language for creating apps for Apple's devices. This article will cover the most frequently asked technical questions in interviews for positions requiring Swift knowledge. If you're looking to hire Swift developers, too, these questions can be a great reference for tests. Let's get started!
Looking for Swift Developers? Build your product with Flexiple's dream talent.
Hire a Swift DeveloperHire NowYou can utilize generic functions and data types in Swift in places like classes, structures, and enumerations.
Code duplication is a problem that is fixed by generics. It's common practice to duplicate a method that accepts one type of parameter so it can also accept a different type of parameter.
For instance, the second function in the following code is a "clone" of the first, except that it only accepts strings rather than numbers.
func areIntEqual(_ x: Int, _ y: Int) -> Bool {
return x == y
}
func areStringsEqual(_ x: String, _ y: String) -> Bool {
return x == y
}
areStringsEqual("ray", "ray") // true
areIntEqual(1, 1) // true
You can consolidate the two functions into one while maintaining type safety by using generics. The standard implementation is as follows:
func areTheyEqual(_ x: T, _ y: T) -> Bool {
return x == y
}
areTheyEqual("ray", "ray")
areTheyEqual(1, 1)
Since you're in this situation testing equality, you limit the type of the parameters to any type that adheres to the Equatable protocol. This code accomplishes the desired outcome while preventing the passing of parameters with a different type.
The distinctions between Swift and Objective-C are as follows:
- Objective-C is a class-based object-oriented programming language, whereas Swift is an object-oriented and functional programming language.
- Unlike Objective-C, which does not support dynamic libraries, Swift does.
- Swift supports tuples, although they are not in Objective-C.
- While semicolons are necessary for Objective-C, they are not in Swift.
- Swift is an open-source programming language, whereas only Apple uses Objective C.
- In contrast to Objective C, where we must define the variable as "NSString" and the constant as "int," we must declare a constant using the "let" keyword and a variable using the "var" keyword in Swift.
- Swift allows us to define methods in structures, classes, or enumerations, unlike Objective C.
- In Swift, classes can be defined in a single file (.swift); however, in Objective C, classes must have separate interface (.h) and implementation (.m) files.
Note: Commonly asked Swift interview questions.
We may declare constants and variables using the Swift language's Let and Var keywords.
- let: The let keyword is immutable; it is used to declare constant variables, which cannot be modified once initialized.
For Example:
The value of myAge cannot be altered; the let keyword can only be used to define it once as a constant value.let myAge = 25
- var is a mutable keyword used to declare variant variables. These alternative variables may alter the run time.
For Example,
We can change the value of myName = "Apple".var myName = "Dell"
The protocol concept, which is analogous to an interface from Java, is common in the Swift programming language. A protocol outlines the necessary qualities, procedures, and specifications for a certain task.
The protocol can be thought of in its most basic form as an interface that describes some operations and characteristics. Instead of describing the implementation, the protocol is only described in terms of its attributes or basic procedures. Enumerations, functions, and classes can be defined to implement properties and methods.
After the names of the structure, enumeration, or class types, protocols are declared. It is possible to make both, a single, and many protocol declarations. Commas separate multiple protocols.
A protocol can be defined in a manner that is very similar to classes, enumerations, and structures:
Protocol Someprotocol
{
// protocol definition goes here
}
We can define multiple protocols, which are separated by commas:
Class SomeClass: SomeSuperclass, Firstprotocol, Secondprotocol
{
// Structure definition goes here
}
Note: Commonly asked Swift interview questions.
A protocol's core function is to specify the capabilities of an unidentified type of object. You may say that it has two or three attributes of different sorts in addition to techniques. However, neither the actual storage for the properties nor anything inside the methods is provided via that protocol.
You can create extensions to your protocols that offer default implementations of the methods in a more complex form. However, you are still unable to offer storage for properties.
Classes, in contrast, are tangible objects. They are not forced to adopt protocols — that is, to implement the necessary attributes and methods — but they may choose to do so.
Classes can be used to build objects, whereas protocols are simply typed definitions. In contrast to classes and structs, which are actual objects you can construct, try to conceive protocols as abstract specifications.
The value of len is 3, meaning that there are 3 elements in arr1. This is so that the arr1 is unaffected because assigning arr1 to arr2 assigns a duplicate of arr1 to arr2.
All the fundamental data types in Swift, such as booleans, integers, and structs, are value types by definition.
Arrays are also a type of value. In Swift, moving a value type around effectively involves manipulating a copy. For instance, a copy of a value type is made when it is passed as an argument to a function, meaning that whatever the function changes, the changes will not be reflected in the original value.
Note: Commonly asked Swift interview questions.
The following are the 5 most frequent execution states:
- Not Running: This is a straightforward condition in which our application is not launched, or in which no code is being performed by the system and terminated, and the application is entirely turned off.
- Inactive: This is merely a temporary state. Our program is running in the background in an inactive state, which prevents it from receiving events.
- Active: The primary execution state, in which our app is running in the background and able to receive events, is active.
- Background: Our app is active and can still perform the background code in this situation.
- Suspended: This status denotes that our application is in the background, that the system has suspended it, and that no code can be executed.
Yes, the way to do it is:
let list = [Int](5...10)
let arrayOfTuples = Array(list.enumerated())
print(arrayOfTuples) // prints [(offset: 0, element: 5), (offset: 1, element: 6), (offset: 2, element: 7), (offset: 3, element: 8), (offset: 4, element: 9)]
or with map:
let list = [Int](5...10)
let arrayOfDictionaries = list.enumerated().map { (a, b) in return [a : b] }
print(arrayOfDictionaries) // prints [[0: 5], [1: 6], [2: 7], [3: 8], [4: 9]]
Structs are immutable because they are the value type. Meaning that other variables cannot, at any time, modify the values of, say, structure.
The self variables' values must be altered inside the function of the structure using the mutating word.
For example
struct MyStruct {
var abc: String = "initila value"
func changeValue() {
abc = "some other value". //Compile time error: Cannot assign to property: 'self' is immutable. Mark method 'mutating' to make 'self' mutable.
}
}
The compile time issue appears when we attempt to modify the value of the variable abc inside the function that is declared in the struct itself.
We must use the mutating method here to update the value inside the structure. Thus, the appropriate code will be:
struct MyStruct {
var abc: String = "initila value"
mutating func changeValue() {
abc = "some other value"
}
}
Note: Commonly asked Swift interview questions.
When writing protocols and protocol extensions, there is a distinction between Self and self.
Self, when referred to with a capital S, stands for the type that complies with the protocol, such as String or Int. The value contained within that type, such as "hello" or 556, is referred to when self is used with a lowercase S.
Consider this extension for BinaryInteger as an illustration:
extension BinaryInteger {
func squared() -> Self {
return self * self
}
}
Keep in mind that any type that complies with the protocol is referred to as Self with a capital S. The method returns an Int when called on an Int in the example above because Int conforms to BinaryInteger.
On the other hand, the self with a lowercase S refers to whatever value the type contains. It would be 5 × 5 if the example above were executed on an Int containing the value 5.
The code shows an Implicit type casting between two data types which is not supported in Swift.
You're attempting to combine three components in the code above, each representing a different data type.
To remedy this, you must change each value to the same data type. For instance,
var result = Double(n1) + Double(n2) + n3
Note: Commonly asked Swift interview questions.
var arr1 = [1, 2, 3]
var arr2 = arr1
arr2.append(4)
var len = arr1.count
The value of len is 3, meaning that there are 3 elements in arr1. This is so that the arr1 is unaffected because assigning arr1 to arr2 assigns a duplicate of arr1 to arr2.
All the fundamental data types in Swift, such as booleans, integers, and structs, are value types by definition.
Arrays are also a type of value. In Swift, moving a value type around effectively involves manipulating a copy. For instance, a copy of a value type is made when it is passed as an argument to a function, meaning that whatever the function changes, the changes will not be reflected in the original value.
Despite the possibility that this code will work, there are two considerations to take into account.
Using hard-coded strings like "West" is not a good idea.The hard-coded strings should be removed, and an enumeration should be made in their place to address this problem.
These changes make the code more understandable and type-safe:
enum Direction {
case North
case East
case South
case West
}
func turnTo(direction: Direction){
switch direction {
case .North: northAction()
case .East: eastAction()
case .South: southAction()
case .West: westAction()
default:
print("No valid direction specified")
}
}
The typealias, as the name suggests, is an alias for an existing data type.
The basic syntax for creating a typealias is as follows:
typealias Size = Float
Now you can use Size instead of Float:
let m1: Size = 150.0
let m2: Size = 220.0
let total: Size = m1 + m2
Closures in action are completion handlers.
Consider a scenario where you conduct a time-consuming job like a network request and want to take action immediately. However, you surely don't want to waste resources by repeatedly determining whether the process is still in motion.
Completion handlers are utilized in this situation. A closure is known as a completion handler "calls you back" as soon as the laborious procedure is over.
A low-level API called GCD (Grand Central Dispatch) manages concurrent operations. This idea is utilized to enhance the functionality of applications. Multiple tasks can be managed simultaneously using this procedure. The best iOS API for multitasking with Async and Sync programming is Grand Central Dispatch (GCD).
- The work is managed by the dispatch queue in FIFO (First In First Out) order. Dispatch queues are thread-safe because numerous threads can access them at once.
- This process has started several tasks concurrently, but it is unsure if it will finish them concurrently. Any order can be used to complete it. They carry out one or more things concurrently at the same time. The intricacy of the work determines completion, not its placement in the queue.
- One task will only run in serial mode at once. It can be applied to coordinate access to a particular resource.
- After the work is finished, a synchronous function returns control to the caller.
- Asynchronous functions instruct the task to begin but do not wait for it to finish, returning immediately.
Swift strings support extended grapheme clusters. Each character contained in a string is made up of a series of one or more Unicode scalars that, when put together, yield a single character that humans can read.
It is impossible to know the number of characters in a string in advance without traversing the full string because various characters can use varying amounts of memory. An extreme grapheme cluster must be examined sequentially to identify which character it represents. Because of this, the countElements function's complexity is O(n).
The Adapter pattern enables the coexistence of classes with incompatible interfaces and wraps itself around the object to present a uniform interface for interacting with it.
The iOS Memento pattern is a state restoration technique. It is possible to return to this externalized state without breaking any encapsulation. In Apple, this method is specifically applied to archiving.
When using Master and producing an instance of Detail and storing a reference to it, and with Detail storing a reference to the instance of its Master creator, there is a strong reference cycle between them. Strong references ensure that neither of the two instances will ever be deallocated, resulting in a memory leak.
Breaking at least one of the two strong ties, either by applying the weak or unowned modifier, is required to find a solution. The differences between the two modifiers' are as follows:
- unowned: The property must be of the non-optional type because it is anticipated that the reference will always have a value during its lifetime.
- weak: The reference may, at some point, have no value; as a result, the property must be of the optional type.
The correct response in the code example above is to specify in Detail that the reference to Master is unowned:
class Detail {
unowned var master: Master
...
}
Note: Commonly asked Swift interview questions.
Tailored Scorecard to Avoid Wrong Engineering Hires
Handcrafted Over 6 years of Hiring Tech Talent