Website Loader
Fork me on GitHub
Homepage Top Icon

PILGRIM

Dependency Injection for Swift

Community project by AppsQuick.ly.

ABOUT PILGRIM

Read More About Us

Take heed!
The wise man does not rest by the roadside inns.

Description

injection

What is Dependency Injection?

Many people have trouble getting the hang of dependency injection, at first. I think part of the problem is that it is actually so simple that we’re inclined to look for something more complicated. With that in mind, imagine that you’re writing an app that gives weather reports. You need a cloud-service (excuse the pun) to provide the data. At first, you go for a free weather report provider, but in future you’d like to integrate a weather service with better accuracy and more features. So like a good object-oriented developer, you make a WeatherClient protocol and back it initially with an implementation based on the free, online data provider.

Without Dependency Injection

It might look like this:

class WeatherReportController : UIViewController {
  let weatherClient = WeatherReportClient(key: myApiKey)
}
                

A problem with this approach is if you wanted to change to another weather client implementation you’d have to go and find all the places in your code that use the old one, and move them over to the new one. Each time, making sure to pass in the correct initialization parameters. A common approach is to have a centrally configured singleton:

class WeatherReportController : UIViewController {
  let weatherClient = WeatherReportClient.shared
}
                

This gets around the problem of having a single point of truth for configuration, but in order to test the WeatherReportController, you now have to test its collaborating class (the weather client) at the same time. This can get tricky, especially as your application gets more complex. Imagine testing Class A, depends on Class B, depends on Class C, depends on… Not much fun!

Enter Dependency Injection:

Rather than seek out collaborators, they are provided externally.

class WeatherReportController : UIViewController {
  private(set) var weatherClient: WeatherReportProvider
  init(client: weatherClient) {
    self.weatherClient = client
  }
}
                

Is that it!?

More or less (dependency injection is, as they say, a $25 dollar term, for a five cent concept) but let‘s look at what happens when we start to apply this approach. If we continue to replace internally resolved dependencies with ones that are provided externally, we arrive at a module where the key actors, their lifecycles and their interactions are defined. This is known as the assembly or composition root.

Pulling construction of these components to the composition root lets your application tell an architectural story. When the key actors are pulled up into an assembly the app's configuration is no longer fragmented, duplicated or tightly coupled. We can have the benefits of singletons, without the drawbacks.

Benefits of Dependency Injection:

  • We can substitute another actor to fulfill a given role. If you want to change from one implementation of a class to another, you need only change a single declaration.
  • By removing tight-coupling, we need not understand all of a problem at once, its easy to evolve our app’s design as the requirements evolve.
  • Classes and structs are easier to test, because we can supply test doubles in place of concrete collaborators (unit tests). Or the real collaborators, but configured to be used in a test scenario (integration tests).
  • It promotes separation of concerns with a clear contract between classes.
  • It is easy to see what each class needs in order to do its job.
  • We can quickly prototype an application architecture - designing the key actors by contract.

Design Goals & Features

Features

Minimal runtime-only library that works with pure Swift (structs, classes, protocols).

Supports Objective-C derived classes, when necessary.

Easy to install. Works on iOS, Mac & Linux. No compile-time weaving required.

Type safe. No reflection or ObjC runtime - uses higher-order functions.

Lifecycles management: Emits built instances with shared, weakShared, objectGraph & unshared scopes.

Simple and flexible. For example, it is easy to have multiple injectable instances that conform to the same protocol.

Provides the notion of a composition root in which key actors and their interactions are defined.

Successor to Typhoon for Objective-C and based on the excellent FieryCrucible.

Use Pilgrim when employing the object-oriented programming paradigm or mixing object-oriented and functional styles of programming.

STARTER TEMPLATE

Read More About Us

“One learns from books and example only that certain things can be done. Actual learning requires that you do those things.” -- Frank Herbert

Quick Start

Have you seen the light?
Use this starter template to get rolling quickly!

WHO IS BEHIND IT?

Read More About Us

"These vagabond shoes are longing to stray. Right through the very heart of it!"
-- Frank Sinatra in "New York, New York!"

Meet The Contributors

Pilgrim is a simple library, however I could still use your help in maintaining it!

Jasper
Blues

Pilgrim

Mac and iOS dev @appsquickly. Graph databases and network science @liberation_data. Open-source veteran.

I Need
You!

Wayfarer

You're a little intimidating, what with the RBF and those arcane spells and all. And you're way smarter than me. You're on my team!

Not Just
Anybody!

Devotee

Life is death. Death is Life. Teach the deserving. Teach with Passion. You will guide us.

And You
Too!

Shaman

In all honesty, you're a pretty freaky guy. None of your jokes make any sense. But you get stuff done. We need you and you got the job, Shaman.

I Didn't
Forget You!

Crusader

We're putting the band back together. People wonder if the Bard adds all that much. You and I know that none of this would be possible without you.

Pilgrim is sponsored by AppsQuick.ly and led by
Jasper Blues.

It’s Q&A Time!

Read More About Us

Pilgrims are persons in motion passing through territories not their own, seeking something we might call completion, or perhaps the word clarity will do as well.

Frequently Asked Questions

Something’s not clear? Check Below!
We tried to answer any question you might have.

Q. Can I ask questions here?

A. Yes.

Please send me a tweet @doctor_cerulean and I will answer as best as I can.

Q. What license is pilgrim released under?

A.Pilgrim is released under the MIT Software License.

Q. How much does it cost ?

A. Nothing! It is free. Just enjoy it.