iOS interview

Ahmed Adam
11 min readJan 19, 2021

How would you describe a Swift language?

It’s a type-safe language for protocol-oriented programming
Safe — fast — expressive
Swift language features

  • Closures unified with function pointers
  • Tuples and multiple return values
  • Generics
  • Fast and concise iteration over a range or collection
  • Structs that support methods, extensions, and protocols
  • Functional programming patterns, e.g., map and filter
  • Powerful error handling built-in
  • Advanced control flow with do, guard, defer, and repeat keywords

POP (Protocol oriented programming)

the protocol is a blueprint of methods.

protocol-oriented is an approach or programming paradigm
In Swift, value types are preferred over classes. However, object-oriented concepts don’t work well with structs and enums: a struct cannot inherit from another struct, neither can an enum inherit from another enum. So inheritance — one of the fundamental object-oriented concepts — cannot be applied to value types. On the other hand, value types can inherit from protocols, even multiple protocols. Thus, with POP, value types have become first-class citizens in Swift.

  • Protocols serve as better abstractions than classes.
    “Don’t start with a class, start with a protocol.”
  • Protocol Extensions
    you can extend a protocol and provide a default implementation for methods, computed properties, subscripts, and convenience initializers.
  • Protocol Inheritance
    A protocol can inherit from other protocols and then add further requirements on top of the requirements it inherits.
  • Protocol Composition
    Swift does not allow multiple inheritance for classes. However, Swift types can adopt multiple protocols. Sometimes you may find this feature useful.

What’s the difference between var and let? Which one would you choose for properties in a struct and why?

Let is used to declare a constant value — you won’t change it after giving it an initial value.
var is used to declare a variable value — you could change its value as you wish
This is why anything weak can't be written using let.
They need to change during runtime and you must be using var instead.

structs get passed by value and not by reference, so you cannot modify the variables in a struct at all after their set. So the let keyword really makes sense.

What are lazy properties?

A lazy stored property is a property whose initial value is not calculated until the first time it is used. You indicate a lazy stored property by writing the lazy modifier before its declaration.

What’s Optional? What mechanism lays behind that? What’s unconditional unwrapping?

A type that represents either a wrapped value or nil, the absence of a value.

This is implemented using a generic enum as follows.
The enum has two cases, to represent the absence and presence of a wrapped instance respectively. When there is no wrapped instance, the value of the optional is .none. When the optional has a wrapped instance, its value is .some, with the wrapped instance as the associated value. Since Optional is a generic type, the Wrapped type parameter is used to determine the type of the wrapped instance at the time an Optional instance is created.

When you’re certain that an instance of Optional contains a value, you can unconditionally unwrap the value by using the forced unwrap operator (postfix !).Unconditionally unwrapping a nil instance with ! triggers a runtime error.

How can we unwrap an Optional value?What’s optional chaining, optional binding, and the nil-coalescing operator?

with if let and guard let serve similar, but distinct purposes.
The “else” case of guard must exit the current scope. Generally that means it must call return or abort the program. guard is used to provide early return without requiring nesting of the rest of the function.
if let nests its scope, and does not require anything special of it. It can return or not.
In general, if the if-let block was going to be the rest of the function, or its else clause would have a return or abort in it, then you should be using guard instead. This often means (at least in my experience), when in doubt, guard is usually the better answer. But there are plenty of situations where if let still is appropriate.

Optional chaining is a process for querying and calling properties, methods, and subscripts on an optional that might currently be nil. If the optional contains a value, the property, method, or subscript call succeeds; if the optional is nil, the property, method, or subscript call returns nil. Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.

Optional binding is a simpler and recommended way to unwrap an optional. You use optional binding to check if the optional contains a value or not. If it does contain a value, unwrap it and put it into a temporary constant or variable.
Swift’s nil coalescing operator helps you solve this problem by either unwrapping an optional if it has a value or providing a default if the optional is empty.

What’s the difference between class and struct?

First, let’s take a look at what classes and structs have in common:

  • They can define properties to store values, and they can define functions
  • They can define subscripts to provide access to values with subscript syntax
  • They can define initializers to set up their initial state, with init()
  • They can be extended with extension (this is important!)
  • They can conform to protocols, for instance to support Protocol Oriented Programming

Classes support a few more capabilities that structs don’t have:

That last point is important: classes are reference types, and structs are value types. Here’s what’s what:

  • Value Type: When you copy a value type (i.e., when it’s assigned, initialized or passed into a function), each instance keeps a unique copy of the data. If you change one instance, the other doesn’t change too.
  • Reference Type: When you copy a reference type, each instance shares the data. The reference itself is copied, but not the data it references. When you change one, the other changes too.

class kept in memory in stack but class in a heap

What are closures?

Closures are self-contained blocks of functionality that can be passed around and used in your code.
Closures can capture and store references to any constants and variables from the context in which they are defined. This is known as closing over those constants and variables. Swift handles all of the memory management of capturing for you.

What do weak and unowned mean? What’s the difference?

A reference to an instance is strong by default. But that is not always what you want. If a strong reference is not appropriate, you have a few other options, weak and unowned references.
Weak References
As the name suggests, a weak reference keeps a weak reference to the instance it references. This means that the reference to the instance is not taken into account by ARC. Remember that an instance is deallocated if no other objects have a strong reference to the instance.
Unowned References
Unowned references are similar to weak references in that they don’t keep a strong reference to the instance they are referencing. They serve the same purpose as weak references, that is, they avoid strong reference cycles.
But there are several key differences between weak and unowned references that are important to understand.
The first difference you need to know about is that an unowned reference is always expected to have a value. This is not true for weak references, which are set to nil if the instance they reference is deallocated. When that happens, the reference is set to nil.
Because a weak reference can be set to nil, it is always declared as an optional. That is the second difference between weak and unowned references. The value of a weak reference needs to be unwrapped before it can be accessed whereas you can directly access the value of an unowned reference.
Be careful, though. If the referenced instance of an unowned reference is deallocated, it isn’t set to nil. As a result, a fatal error is thrown if the referenced object of the unowned reference is accessed.

What’s an autoclosure?

The @autoclosure attribute can be applied to a closure parameter for a function, and automatically creates a closure from an expression you pass in. When you call a function that uses this attribute, the code you write isn't a closure, but it becomes a closure, which can be a bit confusing – even the official Swift reference guide warns that overusing auto closures makes your code harder to understand.

What does the mutating keyword mean?

The mutating keyword is only required if you are changing any state contained within the struct. Since Swift structs are immutable objects, calling a mutating function actually returns a new struct in-place (much like passing an inout parameter to a function). The mutating keyword lets callers know that the method is going to make the value change.

What do escaping and unescaping mean?

Closures are a self-contained block of functionality that can be passed around and used in your code. Closure parameters are @nonescaping by default, the closure will also be executed with the function body. If you want to escape closure, you must execution mark it as @ escaping.
Closure is like a function you can assign to a variable. You can move the variable around in your code, and call the code of the closure at a later point.

The lifecycle of @nonescaping closure,

  • Pass the closure as a function argument, during the function call.
  • Do some additional work with function.
  • The function runs the closure.
  • The function returns the compiler back.

The lifecycle of the @escaping closure:

  • Pass the closure as a function argument, during the function call.
  • Do some additional work in function.
  • Function execute the closure asynchronously or stored.
  • The function returns the compiler

Have you heard about method swizzling? What is that? Can it be done in Swift?

Method swizzling is the process of changing the implementation of an existing selector at runtime. Simply speaking, we can change the functionality of a method at runtime.
yes

What’s the difference between NSArray and NSSet?

The main difference is that NSArray is for an ordered collection and NSSet is for an unordered collection.

NSSet

  • Primarily access items by comparison
  • Unordered
  • Does not allow duplicates

NSArray

  • Can access items by index
  • Ordered
  • Allows duplicates

What’s KVO and KVC?

KVC stands for Key-Value Coding. It’s a mechanism by which an object’s properties can be accessed using string’s at runtime rather than having to statically know the property names at development time.
KVO stands for Key-Value Observing and allows a controller or class to observe changes to a property value.

What’s the application and controller lifecycle?

application lifecycle :
-
Not Running
- In Active
- Active
- Background
- Suspended .

controller lifecycle :
init(coder:)
loadView()
viewDidLoad()
viewWillAppear(_:)
viewWillLayoutSubViews()
viewDidLayoutSubviews()
viewDidAppear(_:)
viewWillDisappear(_:)
viewDidDisappear(_:)
deinit()

What’s Core Data?

Core Data is a framework developed and maintained by Apple.
Core Data is the M in MVC, the model layer of your application.
Even though Core Data can persist data to disk
Core Data is not a database and that it manages your application’s object graph.
If you’re in need of a lightweight model layer, then Core Data shouldn’t be your first choice.
Core Data provides an abstraction that allows developers to interact with the model layer in an object-oriented manner. Every record you interact with is an object.
Core Data is responsible for the integrity of the object graph. It ensures the object graph is kept up to date.
Drawbacks
-
Performance
- Multithreading

What architectures do you have experience with? What’s your favorite and why?

I used MVC , MVVN , VIPER & CleanSwift VIP
my favorite one is VIP because :
- Ready-made templates
- Unidirectional flow of data
- Testability
- Reusability
- Collaboration

What is REST? What’s a difference between the POST and GET methods?

A RESTful API is an architectural style for an application program interface (API) that uses HTTP requests to access and use data. That data can be used to GET, PUT, POST and DELETE data types, which refers to the reading, updating, creating and deleting of operations concerning resources.

GET is used to retrieve remote data, and POST is used to insert/update remote data
POST — The data is included in the body of the request.
GET — pass info is in the URL.

How can we handle background operations?

Operation queue
main thread , global thread
background modes like background fetch

What are the differences and similarities between a GCD and an NSOperation?

GCD is a low-level C-based API.
NSOperation and NSOperationQueue are Objective-C classes.
NSOperationQueue is objective C wrapper over GCD. If you are using NSOperation, then you are implicitly using Grand Central Dispatch.

GCD advantage over NSOperation:
i. implementation
For GCD implementation is very light-weight
NSOperationQueue is complex and heavy-weight

NSOperation advantages over GCD:

i. Control On Operation
you can Pause, Cancel, Resume an NSOperation

ii. Dependencies
you can set up a dependency between two NSOperations
operation will not started until all of its dependencies return true for finished.

iii. State of Operation
can monitor the state of an operation or operation queue. ready ,executing or finished

iv. Max Number of Operation
you can specify the maximum number of queued operations that can run simultaneously

When to Go for GCD or NSOperation
when you want more control over queue (all above mentioned) use NSOperation and for simple cases where you want less overhead (you just want to do some work "into the background" with very little additional work) use GCD

What is a dispatch queue?

A DispatchQueue is an abstraction layer on top of the GCD queue that allows you to perform tasks asynchronously and concurrently in your application. Tasks are always executed in the order they’re added to the queue.

What is a serial queue?

A serial Dispatch Queue performs only one task at the time. Serial queues are often used to synchronize access to a specific value or resource to prevent data races to occur.

What is a concurrent queue?

A concurrent queue allows us to execute multiple tasks at the same time. Tasks will always start in the order they’re added but they can finish in a different order as they can be executed in parallel. Tasks will run on distinct threads that are managed by the dispatch queue. The number of tasks running at the same time is variable and depends on system conditions.

What’s a dispatch group?

A group of tasks that you monitor as a single unit.

Did you ever have a chance to write a custom controller transition? How can we do that?

We don’t do that often, but if we do it’s good to remember about back gestures and know how to implement them.

What’s a difference between frame and bounds?

The “every interview”

Constraint priorities, hugging priority, and compression resistance priority: What are those, and how do they work?

  • Hugging => content does not want to grow
  • Compression Resistance => content does not want to shrink

How would you store sensitive user data?
Keychain

What are generics?

Generic programming is a way to write functions and data types while making minimal assumptions about the type of data being used. Swift generics create code that does not get specific about underlying data types, allowing for elegant abstractions that produce cleaner code with fewer bugs. It allows you to write a function once and use it on different types.

Do you use any dependency manager? Which one do you prefer?

At some point you might want to use 3rd party code to get extra features or something,you can copy the source code but how you will update it in the future? keep coping it again!!

Also some of your 3rd party code might depend on other 3rd part code, and if you copied it twice, you will get duplicate symbols.

Dependency managers handle all this for you.

My advice is to use Carthage or submodules, but do not use CocoPods, anything that touches the project file is not a good practice with Apple.

Do you use Xcode’s instruments? Which ones?

Instruments is a powerful and flexible performance-analysis and testing tool that’s part of the Xcode tool set. It’s designed to help you profile your iOS, watchOS, tvOS, and macOS apps, processes, and devices in order to better understand and optimize their behavior and performance. Incorporating Instruments into your workflow from the beginning of the app development process can save you time later by helping you find issues early in the development cycle.

What is continuous integration (CI)? Do you know and use any? Have you ever configured any?

There’s plenty of them, and it’s good if you know at least one or two.

Do you have experience with unit testing? How about UI testing?

Everyone says they write tests, but do they? If you used any frameworks to help with tests, mention that as well.

What is SOLID? Can you name and describe those principles?

What is declarative programming? Have you tried SwiftUI yet?

What’s reactive programming? Do you have experience with an Rx framework and/or Apple’s Combine?

--

--