Understanding Dependency Injection in Swift

Learn the basics of dependency injection with Swift and Xcode. It will allows you to inject dependencies making classes flexible.

Francesco Leoni

3 min read

What is Dependency Injection?

As the name says, this technique allows you to pass/inject objects (dependencies) to a receiver object. There are two types of dependency injection:

  • Constructor Injection
  • Property Injection

But what is a Dependency? A Dependency is an object (eg. a class) that holds some information. Simple.

An with this technique we are injecting those dependencies into an object, in order to provide the information it needs. So the receiving object will depend on the injected dependencies.

Usually this is done using initializers that accept protocols and passing objects that conform to those protocols or passing the objects through properties.

Now let's see a simple example of Dependency Injection.

Constructor Injection

With the Constructor Injection the dependencies are passed through a custom initializer.

// 1

protocol User {

var name: String { get set }

var surname: String { get set }

}

// 2

class LoggedUser: User {

var name: String = "Jhonny"

var surname: String = "Smith"

}

// 3

class LoginVC: UIViewController {

private let user: User

init(user: User) {

self.user = user

}

}

let user = LoggedUser()

let loginVC = LoginVC(user: user)

  1. We declare a protocol User that requires a name and a surname
  2. Then we create a LoggedUser that conforms to the protocol User
  3. And finally we add an initializer to LoginVC that accepts an User

Tip

Using protocols creates more flexibility since, maybe, in the future we will need another type of user. With this in place we can create a new class that conforms to User a pass it to the LoginVC.

This is Dependency Injection in a nutshell. Isn't it a simple concept?

Property Injection

Unfortunately, the constructor injection is not possible if you are creating your view controllers in the Storyboard, since Swift doesn't allow you to create custom initializers for storyboard.

In this case, the only option you have, is to pass the dependencies after the view controller has been instantiated. And consequently we cannot declare the property as let in LoginVC but we must declare it as an optional var or as a var with a default value, like in the next example:

class LoginVC: UIViewController {

var user: User?

}

let user = User()

let storyboard = UIStoryboard(name: "main", bundle: nil)

let loginVC = storyboard.instantiateViewController(withIdentifier: "LoginVC") as? LoginVC

loginVC?.user = user

Conclusion

In this article we've covered the basics of Dependency Injection. This technique allows you to setup your app in a completely different and more flexible way.

But we will cover this in a different article. In the meantime, I hope you enjoyed this article and that it has been helpful to you.

If you have any question about this article, feel free to email me or tweet me @franceleonidev and share your opinion.

Thank you for reading and see you in the next article!

Share this article

Related articles


Abstract Factory Pattern in Swift

Learn how the abstract factory pattern allows you to improve you codebase making it more readable and maintainable.

3 min read

Patterns

How to Create Swift Macros with Xcode 15

Discover the new Swift Macro, speed up your workflow and make your code easier to read. Available for Swift 5.9 and Xcode 15.

8 min read

Swift

FLCharts: Create Bar Chart easily

Create beautiful and highly customisable bar, line, radar charts and many more with FLCharts, a flexible, easy-to-use library.

3 min read

ChartsSwift