A view master demonstrates dependency injection.

In this article I’m going to explain how you can use Dependency Injection to simplify your iOS ViewControllers to create smaller, more extensible ViewControllers and re-usable Services classes. I will also demonstrate that you can use your Storyboard as a way to configure the dependencies for your ViewController instances.

Dependency Injection?

Dependency Injection is pattern that allows your classes to depend on small re-usable service objects without needing to know how the service objects are created.

This explanation might be a little confusing, so I’ll port one of Martin Fowler’s examples from the link above into Objective-C to clarify.

Take the following class:

@implementation MovieListViewController {
    NSArray *_movies;
    ColonDelimitedMovieFinder *_movieFinder;

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    _movieFinder = [ColonDelimitedMovieFinder new];
    return self;

- (void)viewDidLoad {
    [super viewDidLoad];
    _movies = [_movieFinder findMovies];


As you can see, MovieListViewController has a dependency on an instance of ColonDelimitedMovieFinder which it uses to provide a list of movies when the view is loaded. It could be worse: the movie finding could be a method in the controller (violating SRP1), but we can do even better.

In the following example we make finding movies into a small interface2 upon which the MovieListViewController will depend via a property:

@protocol MovieFinder <NSObject>
- (NSArray*)findMovies;

@interface MovieListViewController : UIViewController
@property NSObject<MovieFinder> *movieFinder;

@implementation MovieListViewController {
    NSArray *_movies;

- (void)viewDidLoad {
    [super viewDidLoad];
    _movies = [self.movieFinder findMovies];

As you can see, we introduced a property for movieFinder to replace the member variable. Also, we introduced a new protocol, MovieFinder which is used as the type of the new property. This is a very simple case of Property Injection3. MovieListViewController is not responsible for creating its movie finding class, instead it is now provided via a publicly writable property.

You may notice that any reference to ColonDelimitedMovieFinder was removed. This doesn’t mean it is no longer a class, but instead it now adheres to the new small interface, for example:

@interface ColonDelimitedMovieFinder : NSObject<MovieFinder>

In addition to injecting this dependency, we have also now made MovieListViewController extensible: it can take any instance of any class that adheres to this new protocol. Now, in addition to ColonDelimitedMovieFinder, there could be a TabDelimitedMovieFinder or IMDBWebServiceMovieFinder on option as well.

Putting Dependencies in the Storyboard

The previous code example is an improvement on where it started, but there is still the open question of where in the codebase the movieFinder property on MovieListViewController gets instantiated and assigned.

There are many ways to do this including:

  • assign a constructed instance of MovieFinder in any previous ViewController’s prepareForSegue
  • have MovieListViewController use ServiceLocator to locate an instance4
  • specify an instance in the Storyboard

Let’s look at how we can use the Storyboard to select the concrete instance of MovieFinder for any given MovieListViewController.

Assume the following definitions exist somewhere in the project:

@interface MovieListViewController : UIViewController
@property IBOutlet NSObject<MovieFinder> *movieFinder;

@interface IMDBWebServiceMovieFinder : NSObject<MovieFinder>

First, add an Object to your ViewController’s scene in the storyboard. Here I have named it IMDBWebServiceFinder with a class type of IMDBWebServiceMovieFinder.

Then control-drag from the MovieList ViewController to the IMDBWebServiceFinder.

And select the outlet named movieFinder.

You can see the outlet connected in the following screenshot:

Now, when the MovieList scene is loaded from the Storyboard, its MovieListViewController will be populated with an instance of IMDBWebServiceMovieFinder. This configuration is stored in the Storyboard and can be changed entirely using only interface builder. Another way to say that is: we are using the Storyboard as our Dependency Injection configuration.5

But Why?

At this point you might be asking why you would ever want to do this. Why not just create your instance of IMDBWebServiceMovieFinder in MovieListViewControllers viewDidLoad: and call it a day?

This is certainly a fine idea and worth considering depending on your circumstances. One of the benefits of this dependency injection method is it allows for the same ViewController implementation to be used for different storyboard scenes with different dependencies.

For example, perhaps this application has a tab for finding movies from IMDB and a tab for finding movies from Netflix.

All you need is a new class adhering to MovieFinder:

@interface NetflixWebServiceMovieFinder : NSObject<MovieFinder>

Now you can create a ViewController in the Storyboard, set the class to MovieListViewController, and instead of connecting a Storyboard Object with type IMDBWebServiceMovieFinder, connect one of type NetflixWebServiceMovieFinder.

Now, in your MovieListViewController, movies can be fetched, iterated, and displayed using the same code, yet the finding of movies is now allowed to vary by this dependency injection.

MovieListViewController in this example is “open for extension, but closed for modification.”6 Or put another way, some of its behaviors (finding movies) can change without the code for listing them needing to change.


One of the main open issues with this approach that it does not yet address dependencies with dependencies. I hope to address this in a future article as it is definitely a larger topic.

Another issue deals with segue names. If you are attempting to use the same ViewController in multiple places in your storyboard, then doing the following is dangerous:

// when the user taps a cell
[self performSegueWithIdentifier:@“NetflixListToMovieDetail];

This is because the segue name is essentially configuration, and that configuration is not being injected from the Storyboard7. One way to put your segue names into the Storyboard is to create a Runtime Attribute in the storyboard containing the the name of the segue which is then available to your ViewController at runtime.

In Short

  • Dependency Injection is an effective and simple way to reduce the size of your iOS ViewControllers.
  • It also allows your view controllers to be open for behavior changes without requiring modifications to the ViewControllers’ implementation.
  • You can optionally inject your dependencies via Objects in your Storyboard
  • This allows for re-use of code, and for treating your Storyboard as configuration.
  • There are potential issues with this solution, namely dependencies with dependencies and putting segue names in your code.

If you are familiar with storyboard objects, then I hope this was helpful in showing how you can use them for dependency injection.

If you are new to dependency injection, then I hope this was a helpful intro showing just one of the many ways you can use it to improve your code and make your programs easier to write and maintain!

Main photo by Flickr user MJM Photographie

  1. SRP: The Single Responsibility Principle

  2. In this case “interface” means “Protocol”. “Small interface” can be explained by this article on the Interface Segregation Principle and other SOLID principles at Bob Martin’s PrinciplesOfOod 

  3. Fowler called this Setter Injection, but it is also known as Property Injection nowadays. You can read more about constructor and dependency injection at this excellent ojbc.io article 

  4. You could, for example, lazy-load some movieFinder from the Service Locator in movieFinder’s getter. This is great for testing as you can still assign a stub or mock of this and bypass the lazy load. 

  5. In Fowler’s Dependency Injection bliki article, he also covered separating configuration from use

  6. More Bob Martin, this time OCP, which is described at PrinciplesOfOod. I’m kind of a nut for these principles! 

  7. You might be able to use the same segue name for all scene instances in your storyboard. According to this stack overflow article it may be possible, but I haven’t tried this.