Trikalabs
  • Home
  • Best online TDD videos
  • Book Suggestions
  • About Me
  • Contact
Trikalabs
No Result
View All Result

Dependency Injection – UIViewController with a Nib file

by fragi
May 13, 2021
in Unit Testing
Share on FacebookShare on Twitter

UIViewControllers are among the most used UIKit objects. As the name implies UIViewControllers are controller objects and their purpose should be to populate data to Views and to react to View actions. They have so many capabilities that often tend to grow in size which leads to massive view controllers, a common code smell in iOS codebases. We should always try to keep them very simple and use separate object for business logic and presentation logic. It should be so simple that unit testing should be trivial on this classes. But sometimes as part of their duty to populate data to the views they might need to use an other class, a collaborator. Clean code practises recommend those collaborators to be injected into the Class, preferably with the constructor dependency injection technique.

In this post we will learn how to use the constructor dependency injection technique when we are using UIViewControllers with Nib files. To keep the example simple and straight to the point we will to try to use a string as the dependency. And the project will have only two UIViewControllers, the initial and the one we want to initialise with the dependency.

The first ViewController has a view with just a button

and it’s code is as simple as :

Swift
1
2
3
4
5
6
7
8
9
import UIKit
 
class ViewController: UIViewController {
 
    @IBAction func didTapPresentAnotherViewController(_ sender: Any) {
 
    }
 
}

The second ViewController’s view has one button and one label, when the user taps on the button the label should show the value of the string that we should pass as a dependency:

And it’s code is as follows:

Swift
1
2
3
4
5
6
7
8
9
10
import UIKit
 
final class AnotherViewController: UIViewController {
    
    @IBOutlet weak var aDependenceLabel: UILabel!
    
    @IBAction func didTapShow(_ sender: Any) {
        
    }
}

All we have to do in order to use the constructor dependency injection technique to pass the dependency into the AnotherViewController class is to use a custom initialiser:

Swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import UIKit
 
final class AnotherViewController: UIViewController {
    
    @IBOutlet weak var aDependenceLabel: UILabel!
    private let aDependency: String
 
    init(aDependency: String) {
        self.aDependency = aDependency
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @IBAction func didTapShow(_ sender: Any) {
        aDependenceLabel.text = aDependency
    }
}

We notice that at the end of our new initialiser we have to call the init of the super method to make sure that the ViewController it initialises properly.

Now when we want to present the AnotherViewController from our first ViewController all we need to do is:

Swift
1
2
3
4
5
6
7
8
9
import UIKit
 
class ViewController: UIViewController {
 
    @IBAction func didTapPresentAnotherViewController(_ sender: Any) {
        let anotherViewController = AnotherViewController(aDependency: "a String")
        present(anotherViewController, animated: true, completion: nil)
    }
}

Run the app, tap to show the AnotherViewController and tap on the button:

fragi

fragi

Related Posts

What is TDD?
Unit Testing

Write better Unit tests with XCTUnwrap

January 27, 2022

Testing optionals can require boilerplate code to unwrap it. It can also affect the readability of the test. Let's look...

Test static method on collaborator
Unit Testing

Test static method on collaborator

May 13, 2021

One of the main issues we are facing when we try to make an old piece of code testable is...

Dependency injection – UIViewController in Storyboard (iOS 13)
Unit Testing

Dependency injection – UIViewController in Storyboard (iOS 13)

May 13, 2021

Finally Apple (iOS 13 +) has added constructor dependency injection to Storyboards! No excuses anymore for not using DI properly...

Unit testing code with DispatchQueue
Unit Testing

Unit testing code with DispatchQueue

May 13, 2021

One way of testing code with DispatchQueue is by using expectations (https://developer.apple.com/documentation/xctest/asynchronous_tests_and_expectations/testing_asynchronous_operations_with_expectations) but in most of the cases it's more...

Unit testing UIViewController LifeCycle
Unit Testing

Unit testing UIViewController LifeCycle

May 13, 2021

Unit testing UIViewController life cycle events are not a straightforward process. Let's have a look on the following view controller:...

Unit Test Post Notification
Unit Testing

Unit Test Post Notification

July 19, 2019

In this article, we will see how we can test code that post notifications. Let's see our example code: ...

Next Post
Unit testing UIViewController LifeCycle

Unit testing UIViewController LifeCycle

Unit testing code with DispatchQueue

Unit testing code with DispatchQueue

Git rebase with SourceTree

Git rebase with SourceTree

  • Advertise
  • Privacy & Policy
  • Contact

© 2019 Trikalabs Ltd. All rights reserved.

No Result
View All Result
  • Home
  • About Me
  • A curated list with the best free online TDD videos
  • Book Suggestions
  • Pinner Code Club

© 2019 Trikalabs Ltd. All rights reserved.