Category: Swift

I am not a big fan of inheritance. I would never say something like “inheritance is evil”, because inheritance, like composition, is just one of the many tools we can reach for, but in my experience, designs based on inheritance tend to be very rigid.

But here is one particular use case where I think the combination of generics and inheritance can provide an interesting solution.

As usual, the example that tries to illustrate this post is not very good. But it is close to my real use case, so I am going to stick with it.

I try to avoid boilerplate as much as possible. That’s why I try to use a generic implementation of the datasource protocols (UITableViewDataSource and UICollectionViewDataSource) to feed all my listings. I even released those datasources as a framework!

The thing is, there is always going to be some particular listing that does not fit completely into that framework. In particular, those listings that require implementing one of the optional methods.

For example, let’s take a look at tableView:titleForHeaderInSection. Do we need a header in every single tableview? Not really, some table views might not even be sectioned.

That method does not seem something that would belong in a generic datasource, because, well, it is there to provide a solution to a very specific use case.

So we could have a generic implementation of the UITableViewDatasource protocol like this (bear in mind I have over simplified it, for brevity):

Mutability is dangerous and I have been aware of the fact for a long time. However, mutability can be sneaky, and make its way into the code without anyone noticing. Sometimes, with disastrous consequences.

First, a little disclaimer. I am a big fan of dependency injection. I have touched the subject in this very blog maybe too many times. I know it is not a golden bullet, I know it is not the solution to every problem, but still, I believe injecting dependencies is, in general, good.

Once that’s out of the way, let’s move on to today’s story. Imagine a view controller that needs to display data fetched from a backend. The integration with said backend is well encapsulated in a class, abstracted by an interface.

A simplified version of this view controller could look like this:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

final class ViewController: UIViewController {

private let data: DataService

init(nibName nibNameOrNil: String?,

bundle nibBundleOrNil: Bundle?,

data: DataService) {

self.data = data

super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)

}

private func fetchData() {

data.allItems { items in

/**

Provide data to a datasource, or present on screen directly, or...

*/

}

}

}

I like this approach: the view controller is provided with everything it needs to work in the constructor, the origin of the data is well abstracted (it could be a remote server, it could be a local database, it could be core data, we don’t care, because we don’t need to know).

But…

This view controller belongs to a storyboard. Dum dum duuuuum.

Here is another disclaimer. I am not a big fan of storyboards for multiple reasons (and the more I use them, the less I like them). But that does not change the fact that this view controller belongs to a storyboard.

So, now, in order to provide it the data service, you have to do something like this:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

final class ViewController: UIViewController {

var data: DataService?

private func fetchData() {

data?.allItems { items in

/**

Provide data to a datasource, or present on screen directly, or...

*/

}

}

}

As far as I know, there is no way to avoid the fact that data can not be assigned a value when the view controller is instantiated. No matter how had I tried to work around it, like making the data variable private and providing a public setter, declaring that setter in a protocol and enforcing compliance in an extension, the fact is that, as far as I know, dataService needs to be a variable, and can not be set when this class is instantiated.

And that is a problem. Because if, for example, you have a segue that leads to this view controller, and you forget to set the value in an override prepareforSegue method, data is going to be nil and DataService.allItems() is not going to be called.

And if you have two segues that lead to this view controller, then you have to make sure that you set the value of data in two different places.

And that’s exactly how my rear got bit. I didn’t notice that second segue, so it was possible to instantiate this view controller without data being set.

You might argue, and you wouldn’t be wrong, that it is my fault, that I am the one that was not setting the value of a variable that is necessary for a part of the system to work properly. Yes, but…

If this class was really immutable (like it is in the first sample), the compiler would enforce that for me. If I do not provide a non-nil value to this view controller’s initialiser, the compiler will not build the project.

And that’s important. Because I am not good at remembering details, in particular details that I somehow consider that I should not need to remember.

In any system, in any codebase of a significant size, special cases, exceptions to the rule, and small details that you have to remember, are a recipe for disaster.

Thanks to multiple painful experiences, I have learnt that this apply to everything. If I need to change a url manually before submitting an app for review, there is going to be a moment when I am going to forget, and submit with the wrong url. If an API needs a parameter named data, and returns data in a parameter named values, sooner or later I am going to mess those up. And if I code a class in a way that it can be initialised in an inconsistent state, by code is going to find a way to initialise that class in the most inconsistent state possible.

I won’t day that “mutability is evil”. There is a place for it. But, this week, I got confirmation, one again, that the best way to avoid problems is allowing the compiler to help me as much as possible.

This post is about one of the Design Patterns, the Template Method. Except for the fact that, well, it is actually about somethign competely different.

Some time ago, in a galaxy far far away, the team I was with was building an internal framework. Our code was supposed to be an amalgamation of rainbows and unicorns that the rest of the company would use as a starting point to build highly customised projects. Yes, it didn’t end well.

But something today made reminisce of a particular episode in that era. Fair warning, some details have been changed to protect the innocent and or make my example a little more relevant.

We were building a video player. The requirements were quite simple: the UI should be easily customisable, and playback events should be trackable (i.e. play, pause, progress), and should be handled in a way that it should be easy to integrate with a second screen solution. Mind you, the company’s business domain was online video delivery, so as you could imagine, this was kind of a big deal.

So, off we went to build the thing, machete in hand and bug spray in pocket.

The key piece of the design was a “manager”, a block of logic that coordinated the playback status with the player’s UI state, while offering a default integration with a second screen solution (also developed in-house).

Now, and this is important, we needed to provide that integration with a second screen solution due to internal business reasons, but the design should be open enough so that other teams could provide their own integrations (i.e. AirPlay or Chromecast)

After some lively discussions we decided to provide what we believed complied with all the requirements.

So, this was, more or less, our manager, translated to Swift 3. Because those were still the Objective-C days.

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

openclassVideoPlayer{

init(){

// initialize all the things

}

funcplaybackStarted(){

// To be overriden

}

funcplaybackStopped(){

// to be overriden

}

funcplaybackProgress(){

// To be overriden

}

// Bunch of private methods here

private funcplay(){

// do stuff that needs to be done

// And then allow subclasses to provide their own behaviour

playbackStarted()

}

}

classInHouseSecondScreenVideoPLayer{

overridefuncplaybackStarted(){

// Implementation that uses the in-house thingy

}

overridefuncplaybackStopped(){

// Implementation that uses the in-house thingy

}

overridefuncplaybackProgress(){

// Implementation that uses the in-house thingy

}

}

The idea was simple. We provided the bulk of the business logic in our manager, and subclasses of our manager should be provided for different integrations with second screen solutions.

Basically, we designed an system modelled after the Template Method Pattern.

If a team wanted to integrate this video player with Chromecast, they would just need to subclass our manager, override the extension points we had provided, and go on their merry way. If another team wanted to integrate with AirPlay, they could do the same.

But, what would happen if a team wanted to integrate with AirPlay and Chromecast?

Well, they could subclass our manager with an integration with Chromecast, and then subclass their Chromecast integration with an AirPlay integration that could call super as part of each method that it overrides.

And that’s my issue with this pattern: it is not exactly what I would consider a very open design.

So, what would be the alternative? As usual, it depends.
To begin with, this pattern can be extremely useful sometimes, and provide very elegant solutions to some problems.

But, in this case, and I guess in any case where an open design is the main goal, it might be better to define an interface for each behaviour that we want to be customisable, and inject them.

For example, we could change the previous design to something like this:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

protocolSecondScreen{

funcplaybackStarted()

funcplaybackStopped()

funcplaybackProgress()

}

final classInHouse: SecondScreen{

funcplaybackStarted(){

// Implementation that uses the in-house thingy

}

funcplaybackStopped(){

// Implementation that uses the in-house thingy

}

funcplaybackProgress(){

// Implementation that uses the in-house thingy

}

}

final classChromecast: SecondScreen{

funcplaybackStarted(){

// Implementation that uses Chromecast

}

funcplaybackStopped(){

// Implementation that uses Chromecast

}

funcplaybackProgress(){

// Implementation that uses Chromecast

}

}

finalclassVideoPlayer{

private letsecondScreen:SecondScreen

int(secondScreen:SecondScreen){

self.secondScreen=secondScreen

}

// Bunch of private methods here

private funcplay(){

// do stuff that needs to be done

// And then allow let the second screen know

secondScreen.playbackStarted()

}

}

letplayer=VideoPlayer(InHouse())

The original design was not bad. This new design, however, has a couple advantages over the original design.

First, the manager and the different implementations of the second screens are more decoupled. The manager can work with multiple different implementation of the second screen, and those implementations of the second screen can collaborate with something other than the manager.

Second, these implementations of second screens are more cohesive, and therefore are going to be easier to test and maintain in the long term. And this part, in my experience, is extremely important. When classes do one thing and one thing only, and all the logic related to that thing is encapsulated in the same class, it is way easier to go back to it months after the code was written.

And third, and more important, now it is way easier to compose behaviours. For example (and I know this is a bad example, but it helps me illustrate my point), if we were asked to send play/stop events to both our InHouse solution and Chromecast and playback progress events only to Chromecast, we could reuse the implementations we already have, like this.

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

final classAllTogetherNow: SecondScreen{

private letinHouse=InHouse()

private letchromecast=Chromecast()

funcplaybackStarted(){

inHouse.playbackStarted()

chromecast.playbackStarted()

}

funcplaybackStopped(){

inHouse.playbackStopped()

chromecast.playbackStopped()

}

funcplaybackProgress(){

chromecast.playbackProgress()

}

}

letplayer=VideoPlayer(AllTogetherNow())

So, I guess, the whole point of this post is “favour composition over inheritance”.

Except, of course, when inheritance provides a better solution to the problem at hand.

So, on second thought, I guess the whole point of this post is that there are trade offs to every approach. A good engineer should try to choose the approach the solves the problem better, with the information she has at hand at that particular moment.

Note: This post has been seating in my drafts folder for months. It is about a topic that has been discussed over and over in this blog, but I still feel like it can add some kind of value. So here you have it.

Dependency Injection and the SOLID principles have become, one way or another, an important part of almost ever post in this blog. And today’s post is no exception.

In my experience, one of the biggest challenges when it comes to unit testing view controllers is, well, unit testing view controllers.

UIKit tends to make all of us lean towards the “one screen = one view controller” paradigm, which tends to make each and every one of those view controllers sort of a dark hole that swallows everything related to the screen it corresponds to.

Yes, as soon as a view controller starts doing more than just the thing it should do (controlling a view), and starts doing networking, navigation, model state validation, local persistency and whatever elese you throw at it, things begin to get complicated.

Well, there is a solution for that: making view controllers do less. Which can be achieved with the help of our old friend, the Single Responsibility Principle. Tell us more about yourself, old friend!

Every module or class should have responsibility over a single part of the functionality provided by the software

The thing about default parameters is that we can use them to help us factor our code in a cleaner and more modular way.

Let’s say that we have a view controller that needs to present a list of Items, fetched from our backend.

We want our view controller to do just one thing, so we will extract the networking to a separate class. Actually, what we do is separate to a different module whatever is related with providing the view controller with the data it needs to display. (See? Single Responsibility Principle FTW!)

So, we could write our view controller like this:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

finalclassList{

letdataLoader=DefaultDataLoader()

vardataSource:DataSource?

overwrite funcviewDidLoad(){

dataLoader.load(completion:dataReceived)

}

private funcdataReceived(data:[Item]?){

dataSource=DataSource(data:data)

tableView.dataSource=dataSource

}

}

This solution is doing the Single Responsibility Thingy properly, but the dependency between List and DefaultDataLoader is hardcoded.

That is an issue, because it is safe to assume that DefaultDataLoader is somehow going to fetch data from the network. Which means that if I want to unit test List, I needs my tests to fetch data from the network, which is in between not optimal and plainly bad.

But why is networking in the tests bad? First, because there is no way to feed the unit tests with custom data, with data that we expect the view controller to handle in an specific way, for example.

Also, because unit tests should only have one reason to fail (again, the Single Responsibilty Principle, this thing is every-frikin’-where!), and doing networking introduces an extra factor for failure. Now a test ight fail because the production code is failing or because the rails server is down, or because the database is down, or because the office dog stepped over the router’s plug and disconnected it.

Oh, is that the bit about Dependency Injection?

Indeed, it is. Actually, it is more about Dependency Inversion, which happens to be the “D” in SOLID.

Depend upon abstractions, do not depend upon concretions.

Or quoting Napoleon and friends again:

Abstractions good, concretions bad!

In our previous example, List depends on a concretion: a specific instance of DefaultDataLoader. That deendency is hardcoded, and it can not be changed after compilation.

Let’s make List depend on an abstraction. One of the tools we have to model abstractions in Swift, line in many other languages, is protocols (interfaces).

So, let’s begin by defining a DataLoader protocol, by just extracting the public API of the DefaultDataLoader class:

1

2

3

4

5

6

7

8

9

protocolDataLoader{

func load(completion:([Item]?)->Void)

}

finalclassDefaultDataLoader:DataLoader{

func load(completion:([Item]?)->Void){

// Do whatever is necessary to fetch data from the backend

}

}

Now, we can inject that dependency into the List class:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

finalclassList{

let dataLoader:DataLoader

vardataSource:DataSource?

init(dataLoader:DataLoader){

self.dataLoader=dataLoader

}

overwrite func viewDidLoad(){

dataLoader.load(completion:dataReceived)

}

privatefunc dataReceived(data:[Item]?){

dataSource=DataSource(data:data)

tableView.dataSource=dataSource

}

}

Dependency Injection is a 20 dollar word for a 20 cent concept. I wish I had come up with that quote, but I didn’t.

But the point is that DI is as simple as that. If class A needs to use class B, pass to class A a reference to class B.

Why do we type it as an interface though? Well, because we want to rely on abstractions, not concretions, remember? And also, because…

Finally! Here comes the ta-dah!

Indeed it comes. The way List looks now, we would need to do somethign like this when initializing it:

1

2

let dataLoader=DefaultDataLoader()

let list=List(dataLoader:dataLoader)

Or if you have a thing for one liners:

1

let list=List(dataLoader:DefaultDataLoader())

Which is fine, but can become annoying if we only need to provide one concrete implementation of DataLoader. And also because, and we are splitting hairs here, that code could look cleaner and read simpler.

And, finally, this is where we get to discuss default values in parameters.

Let’s rewrite the List initializer like this:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

finalclassList{

let dataLoader:DataLoader

vardataSource:DataSource?

init(dataLoader:DataLoader=DefaultDataLoader()){

self.dataLoader=dataLoader

}

overwrite func viewDidLoad(){

dataLoader.load(completion:dataReceived)

}

privatefunc dataReceived(data:[Item]?){

dataSource=DataSource(data:data)

tableView.dataSource=dataSource

}

}

Now, to create an instance of List:

1

let list=List()

It literally, doesn’t get any simpler than that.

But the best is jet to come.

BYOM (Bring Your Own Mock)

Remember what we discussed about unit tests? Yes, unit tests should not hit the network, and we shoud be able to mock data fetched from the network.

Well, the thing is we can unit test List mocking data like this:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

@testable import MyModule

import XCTest

finalclassMockLoader:DataLoader{

privatestructConstants{

staticlet unicorn=Item(id:"")

staticlet rainbow=Item(id:"")

}

func load(completion:([Item]?)->Void){

completion([Constants.unicorn,Constants.rainbow])

}

}

finalclassMediaUsedListTests:XCTestCase{

privatevarlist:List?

override func setUp(){

super.setUp()

list=MediaUsedList(dataLoader:MockLoader())

}

override func tearDown(){

list=nil

super.tearDown()

}

func testWhatNot(){

let something=list.whatever()

XCTAssertEqual(something,23)

}

}

This is Good, with a capital G, because we can provide List with whatever data set we need in order to tests its behaviour, without hitting the wire.

Something happened today that made me go back to a long long time ago, in a continent far far away, when my mentor at the time said to me “program to an interface, not to an implementation”, and I found myself googling (actually, yahooing, it was that long long ago) what that could possibly mean.

It took me years to have a basic grasp of what he meant. And, as I mentioned, today I read some code that made recall that moment.

Let’s say that we are working on an app that needs to save some data locally. Let’s keep things simple and let’s say we need to save a username locally, to pre-populate a login form.

But now, once we are saving and retrieving the user name, it would not be completely unexpected if we were asked to display that username someplace else. Let’s say, for example, why not, that in a splash screen

Code Snippet 2

Swift

1

2

3

4

5

6

7

8

9

10

final classSplashScreen: UIViewController{

@IBOutlet weakvarusername:UILabel!

overridefuncviewDidLoad(){

letdefaults=UserDefaults.standard

ifletname=defaults.value(forKey:"username")as?String{

username.text=name

}

}

}

I guess by now you already see the problem.

We are duplicating code. And duplicating code is not good.

But, even if we were not duplicating code, there is another issue here, way more subtle in my opinion.

And the issue is that the code is Snippet 1 is highly procedural, and it is a clear example of programming to an implementation, and not to an interface.

Programming to an implementation

The code in sample 1 is highly imperative and extremely specific. It lacks any abstraction.

We are aware, and we express that clearly in the code, that the username is going to be stored in the user defaults. Not only that, we make the LoginScreen class aware of that fact, and what is worse, we make it also aware of how saving stuff to user defaults work, in painful detail.

This code was easy to write, but the fact that we are exposing the details of how the username is saved is going to be a guaranteed source of pain.

What would happen if we needed to save, for example, the user’s phone number as well? Or his score (if this was a game)? Or an authentication token? And what if we also need to display any of that data in more that one place? We would scatter our source code with extremely specific references to the way we read/write that data.

Programming to an interface

The way I see it, programming to an interface is avoiding implementation details to be known by anyone that should not be aware of said details. And the way to achieve that, is by making my code as declarative as possible.

So, what do we have here? We have data that can be used to identify a User, and we need behaviour to make that data persist between app sessions.

Model objects

So, the first thing to do is identify the Model. In this example, the model is not a username or a telephone number, or a token, it is the abstraction that groups all of those together: a User.

So, let’s declare a User:

Code Snippet 3

Swift

1

2

3

4

structUser{

letname:String

letphone:String

}

Abstract behaviours

Now, what do we need to do with that User? Persist it. Do we need to know how to persist it? No, we don’t. Do we need to know if we save it to UserDefaults, to a remote server, or to the Keychain? No, we don’t.

And this is the whole point of this post: more often than not, we don’t need to know how something is done, we just need to know that something is going to get done. In this case, we don’t need to know how the user’s data is going to be saved, all we need is to know that someone is going to take care of having that data available for us when we need it.

That way, we shift from writing step by step descriptions of what to do, to write high-level expectations of how things should collaborate with each other. We shift from imperative, to declarative code.

So, what’s the behaviour here? If we describe what we need in the most possible abstract way, we need User data to be available.

Abstract stuff, in Swift, like in any other OO language, is the domain of interfaces. In Swift, though, we call the Protocols.

Code Snippet 4

Swift

1

2

3

4

protocolDataStore{

funcsave(user:User)

funcread()->User?

}

And protocols need an implementation:

Code Snippet 5

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

final classLocalStore: DataStore{

funcsave(user:User){

letdefaults=UserDefaults.standard

defaults.setValue(user.name,forKey:"username")

defaults.setValue(user.phone,forKey:"phone")

}

funcread()->User?{

letdefaults=UserDefaults.standard

guard letname=defaults.value(forKey:"username")as?String,

letphone=defaults.value(forKey:"phone")as?Stringelse{

returnnil

}

returnUser(name:name,phone:phone)

}

}

Now, the original code would look like this:

Code Snippet 6

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

final classLoginScreen: UIViewController{

@IBOutlet weakvarusername:UILabel!

@IBOutlet weakvarphone:UILabel!

private letstorage:DataStore=LocalStore()

//Save the username

private funcsave(){

guard letname=username.text,

letphone=phone.textelse{

return

}

letuser=User(name:name,phone:phone)

storage.save(user:user)

}

//Read the username

private funcread(){

ifletuser=storage.read(){

username.text=user.name

phone.text=user.phone

}

}

}

Which is better, if you only look at the save() and read() methods.

In fact, you might be wondering if we are actually in a better position now. We have written a protocol, to abstract things, but after all, in LoginScreen we create a concrete class to implement it. And you would be right, if it wasn’t for the coming step.

If we pass LoginScreen the actual implementation of the DataStore protocol that we want it to use, LoginScreen wouldn’t actually know who or how is saving and fetching data. That is called “inverting the dependency”. And I have written about it a couple times before.

Code Snippet 7

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

final classLoginScreen: UIViewController{

@IBOutlet weakvarusername:UILabel!

@IBOutlet weakvarphone:UILabel!

private letstorage:DataStore

init(storage:DataStore,nibName:String?,bundle:Bundle?){

self.storage=storage

super.init(nibName:nibName,bundle:bundle)

}

required init?(coder aDecoder:NSCoder){

fatalError("init(coder:) has not been implemented")

}

private funcsave(){

guard letname=username.text,

letphone=phone.textelse{

return

}

letuser=User(name:name,phone:phone)

storage.save(user:user)

}

//Read the username

private funcread(){

ifletuser=storage.read(){

username.text=user.name

phone.text=user.phone

}

}

}

Now we are getting somewhere. We have one abstraction (DataStore) and we have a class (LoginScreen) that is provided with a concrete, and unknown to it, implementation of that abstraction. We have shifted from something extremely specific and imperative (LoginScreen saving and reading to user defaults) to something abstract and declarative (LoginScreen asks DataStore to save or fetch data, not caring about how it does it).

And, to me, that is what “program to an interface, not an implementation” means.

Now let’s imagine that we want to present the number of workouts that can be still tracked in the current month in one of our views. Given the previous model, we could do something like this:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

final class Current: UIViewController {

/**

Returns number of available workouts, according to the user's account tier, to be presented on screen

*/

funcworkoutsAvailable(account:Account)->String{

letreturnValue:String

switchaccount.tier{

case.free:

returnValue="20"

break

case.plus:

returnValue="50"

break

case.premium:

returnValue="unlimited"

break

}

returnreturnValue

}

}

I guess you immediately recognise an issue here: the logic in the workoutsAvailable function should be part of the Account object.

There are multiple reasons for that. First, well, that logic is part of the Account abstraction. Second, if we need to present the number of available workouts in two different places in the UI, we would have to duplicate that logic.

So, let’s do the right thing and move that code to the Account entity

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

enum Workout {

case running

case hiking

case walking

case biking

case swimming

case yoga

case pilates

case rollerDerby

}

struct Account {

enum Tier {

case free

case plus

case premium

}

let id: String

let tier: Tier

var workoutsAvailable: String {

let returnValue: String

switch tier {

case .free:

returnValue = "20"

break

case .plus:

returnValue = "50"

break

case .premium:

returnValue = "unlimited"

break

}

return returnValue

}

}

final class Current: UIViewController {

/**

Returns number of available workouts, according to the user's account tier, to be presented on screen

*/

funcworkoutsAvailable(account:Account)->String{

returnaccount.workoutsAvailable

}

}

It is obvious that the way clients of the Account entity can present the number of available workouts is simpler now. That is important for many different reasons, but to men the most important is readability. Reading and understanding the code in the Current.workousAvailable function takes a second, because there is no complicated logic to understand in there. And as a bonus, when there is no complicated logic to read and understand, it is more difficult to make mistakes.

But now, we also need to present the monthly price in the UI. given our previous experience with the number of available workouts, we might go directly to add that logic to the Account struct

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

enumWorkout{

caserunning

casehiking

casewalking

casebiking

caseswimming

caseyoga

casepilates

caserollerDerby

}

structAccount{

enumTier{

casefree

caseplus

casepremium

}

letid:String

lettier:Tier

varworkoutsAvailable: String{

letreturnValue:String

switchtier{

case.free:

returnValue="20"

break

case.plus:

returnValue="50"

break

case.premium:

returnValue="unlimited"

break

}

returnreturnValue

}

varprice: String{

letreturnValue:String

switchtier{

case.free:

returnValue="Free"

break

case.plus:

returnValue="2 USD"

break

case.premium:

returnValue="10 USD"

break

}

returnreturnValue

}

}

(As a side note, the price should not be typed as a string, but as another struct called Currency, with two properties: the value and the unit it is measured in. But that’s beyond the scope of this post)

Now, notice how the Account struct is basically has the same logic duplicated in two calculated properties. Now, if we add the supported workout types to the mix, we would have three different properties implementing more or less the same logic.

We are turning our Account abstraction into something that can do three different things, depending on a type parameter.

We have code that affects the behaviour of a class, according to an internal enumeration. That is a good indicator that, maybe, the Account struct should be broken down into different classes, each and every one of them modelling only one of those behaviours.

So here is where the refactoring in the post title comes to help.

What do we really need our accounts to provide? Price, number of workouts and a boolean that tells us if that account can track a particular workout type.

Let’s model that as a protocol:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

enumWorkout{

caserunning

casehiking

casewalking

casebiking

caseswimming

caseyoga

casepilates

caserollerDerby

}

protocolAccount{

varworkoutsAvailable: String{get}

varprice: String{get}

funccanTrack(workout:Workout)->Bool

}

Now, and this also might be a matter for another post, there is something in that protocol that I find a little bit annoying: the lack of symmetry. So I am going to refactor it to:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

enumWorkout{

caserunning

casehiking

casewalking

casebiking

caseswimming

caseyoga

casepilates

caserollerDerby

}

protocolAccount{

funcworkoutsAvailable()->String

funcprice()->String

funccanTrack(workout:Workout)->Bool

}

Now, I shall provide a different implementation of this protocol for each account tier:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

enumWorkout{

caserunning

casehiking

casewalking

casebiking

caseswimming

caseyoga

casepilates

caserollerDerby

}

protocolAccount{

funcworkoutsAvailable()->String

funcprice()->String

funccanTrack(workout:Workout)->Bool

}

structFree: Account{

funcworkoutsAvailable()->String{

return"20"

}

funcprice()->String{

return"Free"

}

funccanTrack(workout:Workout)->Bool{

return(workout==.running||

workout==.hiking||

workout==.walking)

}

}

structPlus: Account{

funcworkoutsAvailable()->String{

return"50"

}

funcprice()->String{

return"2 USD"

}

funccanTrack(workout:Workout)->Bool{

return(Free().canTrack(workout:workout)||

workout==.biking||

workout==.swimming)

}

}

structPremium: Account{

funcworkoutsAvailable()->String{

return"Unlimited"

}

funcprice()->String{

return"10 USD"

}

funccanTrack(workout:Workout)->Bool{

returntrue

}

}

Now, each struct models a simple behaviour. There is more code, true, but the code is dumber, simpler. Each logical unit (struct) model a single behaviour. That makes the code easier to read, easier to understand, and therefore more robust and easier to maintain.

TL;DR;

iOS apps have a single entry point. That single entry point can create and hold a reference to whatever we need to be global, and then inject it everywhere.

Object Oriented Design, or Architecture if you will, is a daunting topic. I believe there is never a right or wrong way to architect a software project, because the number of tradeoffs to consider is huge, so what works for a project might not be the optimal solution for the next one.

That being said, I do believe there are a basic set of practices that help build highly cohesive and decoupled code: single responsibility principle, modularity, a set of domain model objects, and dependency injection.

To illustrate my point, let’s discuss at a very simple app, that reads and writes data from and to a backend. I guess that, conceptually, covers almost 100% of the apps that are developed these days. Let’s say it is a todo list.

Domain model objects

The first step would be looking at the domain (the problem we are trying to solve) and come up with a set of abstractions that model the entities that are part of it.

In our example, we want to display todo’s, create todo’s, present a list of todo’s, and maybe share todo’s… I guess by now we all can see a model object emerging: Todo

Swift

1

2

3

4

5

structTodo{

letid:String

lettitle:String

letdue:Date

}

Data manipulation.

We need to send Todos to a backend. And we need to read Todos from a backend as well. That probably implies dealing with network requests, and also with a good deal of JSON (or protocol buffers).

We don’t want to scatter those responsibilities across the codebase, even if it is just because network operations have to be done in a background thread, to avoid blocking the UI, so it makes sense to deal with all that async calls in just one place.

But, we have a difficult solution here: that one thing dealing with networking will have to be used from multiple places

Singletons, per se, are neither good nor bad. Sometimes, something is a singleton and it makes sense to model it as such.

But, in my experience, it is better to move away from them, for one reason in particular: a singleton is a global variable, and as such it is a dependency that is very hard to get rid of.

Dependency Inversion

But what if we invert that dependency? And we have a huge advantage here: the iOS app architecture.

An iOS app has a single entry point (the AppDelegate, an implementation of the AppDelegate protocol).

That ensures that instances variables of the AppDelegate are going to be unique as well. Well, not completely, but let’s say that we can guarantee that an instance of a regular class is created once and only once.

You might say, and you would be right, that there is nothing preventing a developer from creating as many instances of that class as she wants. I believe the solution to that is, as Uncle Bob said, well, just create one.

Back to Data Manipulation

Another look at the domain will tell us that we want to:
– obtain a list of Todos
– obtain a Todo
– create a new Todo
– edit an existing Todo
– delete a Todo

This nothing more than a list of high level operations. We don’t really care, or need to care, at this stage about how those operations are actually implemented, so we can just declare them as a protocol.

Swift

1

2

3

4

5

6

7

8

9

10

typealiasSingleTodo=(Todo?)->Void

typealiasMultipleTodo=([Todo]?)->Void

protocolTodoService{

funcall(completion:MultipleTodo)

functodo(id:String,completion:SingleTodo)

funcsave(todo:Todo)

funcdelete(todo:Todo)

}

Notice how this protocol abstracts two different responsibilities: reading and writing. This is a hint that, eventually, we might need to split the protocol in two (again, this post provides a great discussion of why it might be a good idea to do so).

However, I am not going to do it right now, in part because it is one of the points I want to make: modularity, good separation of concerns, empowers us to further break things down whenever we things it is the right moment to do so.

Now all we have to do is provide an implementation of that protocol to our UI. And the easiest way to do that is, again, relying on the fact that we have a single entry point (the App Delegate), and applying the Dependency Inversion principle. Or, if you will, inject all the things!

I am not very fond of storyboards, so I usually have a class whose responsibility is bootstrapping the UI, creating the root view controller, the navigation logic (if necessary) and preparing both for collaboration.

I create that bootstrapping logic in the App Delegate, and I would also create an instance of my service, and inject it into the bootstrapping logic:

Is this approach future-proof?

Nothing is completely future-proof, but I think this approach is flexible enough, and to me, it remains open enough for modification and extension.

There is good separation of concerns. There is one thing that deals with data (fetching and saving), there is one thing that creates UI, and there might or might not be one thing that handles navigation.

There is good modularity. Any of those things in the previous bullet point can be refactored and split into smaller pieces, if necessary. There is a clearly defined interface in between them, so if, say, I noticed that the implementation of my TodoService is starting to mic business logic and pure data transport, I can break it down in two.

There is good testability. Since I am injecting the TodoService into each view controller that needs to collaborate with it, I can inject a mock in my tests.

I have found that by pursuing a dependency graph in the form of a tree, where the root node is the App Delegate, I have more room for adapting to changing requirements, and I can factor and test my code better.

This week I spent some time adding a media gallery to the product I’m working on. You know, one of those things that mimic the native Photos user experience, where you can swipe to left and right to navigate to the next item, zoom in and out a photo… The usual suspects.

So, in order to move fast we decided to rely a third party library for it, instead of writing it from scratch.

We already had a well defined model object to represent a media item (photo or video). But the third party library that we chose requires its own model object, which makes total sense.

Also, it is possible we might end up switching to a different library in the nearly future, so it makes sense to have a clear boundary between our code and the third party library. I call it a boundary, some people call it a wrapper, some other people would call it an abstraction layer, but the point is that we don’t want to scatter references to this third party library across our codebase, we want those references to be isolated, encapsulated in just one class.

We could discuss if having a property to mark a MediaItem as an image or a video is an indication that MediaItem is the wrong abstraction, but that’s beyond the scope of this post (hint: I think it is the wrong abstraction, that any kind of type property in any class or structs suggests that there we are trying to model two different things with just on type)

Let’s say that boundary is a class Called MediaBrowser, that, first of all, transforms our model objects to instances of the model objects required by the third party library:

Swift

1

2

3

4

5

6

7

8

9

10

11

final class MediaBrowser {

func galleryData(media: [MediaItem]) -> [GalleryItem]? {

return media.flatMap{ mediaItem in

let isMovie = (mediaItem.type == .Movie)

let url = isMovie ? mediaItem.videoURL : mediaItem.imageURL

let type: GalleryItem.GalleryType = isMovie ? .Video : .Image

return GalleryItem(url: url, type: type)

}

}

}

Now, that code might look quite straight forward, but in plain english, it will read like this:

For each instance of MediaItem, create an instance of GalleryItem, having in mind that, when creating an instance of GalleryItem, first, we need to check if MediaItem is a photo or a video. If it is a video, we need to pass to GalleryItem’s initialiser the value of the videoURL property in MediaItem, mark it as Video. However, it MediaItem is of type Image, we need to provide its imageURL to GalleryItem’s initialiser, as well as mark GalleryItem as Image.

It’s not rocket science. But describing what galleryData() code does requires a paragraph. And every single time you read this function, you need to translate it into that paragraph in order to understand what it is doing.

That happens because the code is quite imperative . There are a lot of specific, unnecessary details in there. Unnecessary because we don’t need to be that specific to describe what we expect the galleryData() function to do.

This is what we expect: we want to map each instance of MediaItem to a brand new instance of GalleryItem. Simple as that. However, the code, again, is telling a different, more complex, story, with plenty of details that we don’t need to be made aware of every time we read it.

The declarative solution

One of the things I like most about Swift is that it provides multiple ways to model abstractions, and multiple tools that can be used to write more declarative code.

For example, we can declare initialisers in extensions. So, we could do something like this, to extend the GalleryItem object (remember, this object is part of a third party library, and therefore out of our control):

Swift

1

2

3

4

5

6

7

8

9

extension GalleryItem {

init(mediaItem: MediaItem) {

let isMovie = (mediaItem.type == .Movie)

let url = isMovie ? mediaItem.videoURL : mediaItem.imageURL

let type: GalleryItem.GalleryType = isMovie ? .Video : .Image

self.init(url: url, type: type)

}

}

And now, this would be our galleryData() function:

Swift

1

2

3

4

5

final class MediaBrowser {

func galleryData(media: [MediaItem]) -> [GalleryItem]? {

return media.flatMap{GalleryItem(mediaItem: $0)}

}

}

This function, now, clearly express my expectation: I want to create a new GalleryItem for each MediaItem. Period. I don’t care about how that happens, I don’t care about the details, I just trust GalleryItem to do the right thing and create an instance of itself correctly.

We have turned the previous, imperative code into declarative code.

Now, in plain English the galleryData() function reads:

For each instance of MediaItem, create an instance of GalleryItem.

Rinse and repeat

In the scope of this post, there is not a huge difference in terms of lines of code, or in terms of code complexity between both solutions. This, per se, is not going to turn complex code into simple code, buggy code into robust code.

TL;DR; every time I find myself in a situation where I need to unit test a private behaviour, I consider that a clear indication that I might need to rethink my design.

Let me tell you a story

Some time ago, in what now seems like a galaxy far far away, I was introduced to unit testing by means of someone adding the following requirement to the project my team was developing: “code must be unit tested”.

As you can probably guess by the hint of sarcasm in the previous paragraph, unit testing, like almost everything else in life, is something you learn, not something you are born with. Which was painfully obvious at that time, as I have already written about.

But the thing is, a couple days ago I finally had the opportunity, since I was trapped in a plane for 13 hours, to catch up with some reading. In particular I was finally able to devour Sandy Metz’s new book.

The book is still unfinished, but I highly recommend grabbing a copy, and reading it cover to cover, as soon as possible.

There are plenty of potential quotes in that book, but I would like to focus on one in particular:

… the first step in learning the art of testing is to understand how to write tests that confirm what your code does without any knowledge of how your code does it.

Tests always tell at least two stories.

Unit tests always tell at least two stories. One, specially if the tests are well written, is a cristal clear description of the expectations you have about the behaviour of the code under test.

The second story, though, is usually one that nobody likes to hear. If your tests need to manipulate internal behaviour of the code under test, in order to test your external expectation of that code, then you need to rethink your design. And allow me to illustrate this with an example, that links with the introduction to this very same post you are reading.

When testing goes wrong.

Back to my story: no one in our team had any experience testing, so at the time we did not recognise the code smell, but here is what we were trying to do.

We had this one class that was supposed to be a one to one mapping to a RESTful API, what in the classic three-tier architecture would correspond to the data tier, service layer, transport layer, whatever you call it. The point is, this was the class that performed networking operations against a RESTful API. Let’s call it MediaService.

Part of the expected behaviour of MediaService was that it should cache data, using a key-value cache. This data cache would expire after a given time.

So, the flow would be like this: with every request, we would first check if there was data cached and not expired. If there was data cached, MediaService would return it, if there was no previously cached data or the existing data was marked a expired, MediaService would attack the network, fetch data, and add it to the cache, associating a timestamp to each key-value pair.

So, the next time we wanted to request data to the same endpoint, we would check the cache again, providing a timestamp. The cache would calculate if data was expired or not… rinse and repeat.

In code, that looked similar to the following snippet (those still were the Obj-C times, so this is a rough translation to Swift of my recollection of the events):

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

/**

This should be a struct, I know, but those were the dark times, before generics and the coming of value types.

//Attack the nework, fecth and parse result, and add parsed Movie to the cache

}

return nil

}

}

Well, not very idiomatic Swift code, of course, but again, those were the dark days before generics.

Now, if you wanted to test that cache was ignored when cached object have expired… how would you do that?

Dependencies

I don’t recall who said it, but someone said that good software engineering is all about arranging the code in a way that complexity does not collapse on you.

That usually implies breaking down your codebase, organising it into separate subsets or structures. Since you are already breaking down your code and organising it in smaller chunks, you might as well make each of those chunks contain code that is related, that deals with one concern. So, instead of one big ball of code, you would end up having smaller balls, each one of them taking care of one and only one smaller part of the big problem your software is trying to solve. (That’s how I visualise cohesion, by the way)

But of course, the problem your software tries to solve is bigger than each and everyone of those small, cohesive structures that you have used to organise your code. So they need to collaborate with each other.

And here is where dependencies are born. One block of code needs to collaborate with another block of code. One part of your solution needs to collaborate with another part of your solution. Or, if you will, one part of your solution depends on another part of the solution.

The tricky part here is how to set up those dependencies in a way that do not defy the whole purpose of breaking down your code into smaller structures. The key is setting up those collaborations in a way that the collaborators are still independent from each other.

Depending on abstractions not concretions

In the previous code sample, MediaService needs TimeCache. The key here is that it actually depends on the existence of TimeCache, because MediaService creates TimeCache, therefore the behaviour provided by TimeCache is, in a way, embedded within MediaService. Or, the MediaService abstraction depends on the implementation details of TimeCache.

But, why does that matter?

Firstly, MediaService is tightly coupled to TimeCache. So coupled to it, that it actually needs to create it in order to make itself functional.

Secondly, and due to the previous point, it is not possible to modify the behaviour of TimeCache, without modifying MediaService.

Thirdly, there is a more subtle issue here. The fact that there is a cache, and the fact that said cache expires, is not part of the public API of the MediaService class. It is an implementation detail, buried into the MediaService class code, but an implementation detail that is so significant that leaks outside its container. Because we know MediaService handles a cache that marks items as expired, because we expect actually expect that, however, the expectation is not declared anywhere in MediaService’s public interface.

So now, when it comes to unit testing, we face a very interesting problem: we need to test a behaviour that is a private implementation detail, but since we need to test it, it is not private anymore, it is a well-known expectation, but an expectation that we can not test because it is a private implementation detail. You see the infinite loop here, right?

And notice how I have not even mentioned networking…

No worries, mocks, stubs and spies can help!

Well, not anymore. In the old Objective-C days, we could just declare a category in the testing bundle to expose and override any private property of a class with a mock (or stub, or spy, to be honest, I never really understood the difference).

In this case, we could override cache and network, provide mocks, set our tests, and go on our merry way.

The problem with that is that we would still be testing private behaviour. And why should not do that?

The reason, is again, subtle. When we test private behaviour we are basically coupling our tests to the production code very tightly, because we are not testing public APIs anymore, we are testing internal implementation details we should not even be aware of.

Have you ever heard anyone complaining about how unit testing is a waste of time and effort because if you change the production code there is always going to be a bunch of tests that need to be rewritten? I bet the reason is because of vey tight coupling between tests and the code under testing. Or, in other words, because the tests are not testing why they should (public expectations) but private details about how those expectations are fulfilled.

Also, in the age of Swift, doing that is not even possible anymore. If MediaService is final, we can not subclass and override, and if cache and network are declared as constants with let there is no way to override them.

But that’s for a reason. Inverting the dependencies, in my experience, only has upsides. It makes code more decoupled, easier to test, and therefore easier to maintain in the long term.

In this case, the best solution would be something along these lines:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

protocol Cache {

func object(key: String) -> AnyObject?

func set(value: AnyObject, key: String)

}

final class TimeCache: Cache {

/// Implement protocol

}

protocol Network {

func post(args: [String: String])

}

final class NetworkClient: Network {

//Implement protocol

}

final class MediaService {

private let cache: Cache

private let network: Network

init(network: Network, cache: Cache) {

self.network = network

self.cache = cache

}

}

Cache and networking behaviours can be provide now through the MediaService initialiser. Notice the shift in the way we refer to caching and networking now: as behaviours. Because for MediaService, that’s what they are.

The details on how caching and networking work are not known to MediaService anymore. MediaService is provided the behaviours it needs to rely on, the behaviours it needs to collaborate with.

And that’s the beauty of inverting the dependencies. By carefully setting the way collaborators know about each other, and by carefully hiding whatever is not necessary for collaborators to know, and by shifting from concretions to abstractions we make each of our building blocks rely on the expectations that the other building blocks publish about their own behaviours.

Third party libraries are great. I am even guilty of releasing a couple of them myself, but the thing is that I believe pulling in a third party dependency should be carefully considered.

The advantages and disadvantages, the benefits and risks of relying on third party libraries are definitelly worth a separate post. But, for now, let me just say that I think relying on third party code is a commitment that needs to be very carefully considered. It is a dependency on code that is out of your control.

But back to the post at hand. Even though the existing third party JSON parsers and serializers are great, I tend to do all my JSON parsing manually.

Why? First of all, check the previous paragraph. I am not for reinventing the wheel at all, but so far, I haven’t found myself in any situation where relying on a third party library had any sensible advantages over rolling out my own parsing.

An object should know how to serialize and materialize itself. Now, when it comes to simple model objects (kind of a POJO), it could be argued that embedding that knowledge into an object is not the best possible idea. After all, the NSCoding approach implies that a model object would need to know the specifics of a format (JSON, XML, plist, or whatever the cool kids do at the moment), and that knowledge should not be part of the model object itself.

But Swift provides awesome tools to model this in a modular way. Like, for example, extensions. So we could still declare our model object as a simple entity, without any behaviour:

1

2

3

4

5

6

7

structBlogPost{

let id:Int

let text:String

let thumbURL:NSURL

let linkURL:NSURL

}

And then declare a failable initializer that creates an instance of BlogPost from JSON data in an extension:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

extensionBlogPost{

privatestructKeys{

staticlet id="id"

staticlet text="text"

staticlet thumbURL="thumb_url"

staticlet linkURL="link_url"

}

init?(JSON:AnyObject){

guard let id=JSON[Keys.id]as?Int,

let text=JSON[Keys.text]as?String,

let jsonThumbURL=JSON[Keys.thumbURL]as?String,

let jsonLinkURL=JSON[Keys.linkURL]as?String,

let thumbURL=NSURL(string:jsonThumbURL),

let linkURL=NSURL(string:jsonLinkURL)else{

returnnil

}

self.id=id

self.text=text

self.thumbURL=thumbURL

self.linkURL=linkURL

}

}

The code looks clean enough to me, I am still complying to the single responsibility principle, and I still have good separation of concerns.

If I needed to materialize a BlogPost from a different format, say a plist file, all I would need to do would be add a new extension with a new failable initializer.