In the following tutorial, we will build a sample iPhone app that communicates internally via Signals, a Swift library for creating and observing events.

Introduction

Plumbing, architecture, boilerplate. Whatever name you choose, finding the best way of doing the boring stuff of moving stuff around your app safely and efficiently is a problem we all have to address. Signals by Tuomas Artman via Dependency Injection is my favoured approach. A Signal is an event that is broadcast and can be listened to by other classes, and reacted to if needs be.

Dependency Injection and MVC

The cleanest way to implement Signals is to inject a singleton-with-a-small-s Signals' event bus as a "service" using Dependency Injection. Don't fret if the preceding sentence was Greek to you, I have written a tutorial about Dependency Injection here, which you might want to read first, and I will explain the rest below.

In MVC - or Model-View-Controller - driven development, apps cleanly separate their user interfaces from the data they display, and the Model is the part of any given app that deals solely with data. MVC Models are chiefly constructed from two types of classes:

  1. proxies, that store data; and
  2. services, that transport data.

What we will do is to create a single instance of a class called SignalsService, and then inject it throughout our application.

Creating SignalsProtocol

If you've digested my Dependency Injection tutorial, you will know that the first thing we need to create is a protocol for our service. Create a new Swift file called SignalsProtocol.swift and add the following code:

This is a complete list of the basic functions needed to make the bus work. Let's implement them one-by-one.

Create a new Swift file called SignalsService.swift and add the following code:

This implements the four functions in the protocol. Instances of other classes will use these four methods to listen for and stop listening for signals, and to dispatch and delete signals. It imports Signals at the top, which is Tuomas Artman's library that you will need to add to your project via Cocoapods or Carthage. It also adds the private variables _signals and _signatures, which we will use later to store our signals.

Initialise these two variables immediately thus:

Next add the following private function:

This function checks whether a given listener already exists or not, and returns a Boolean. As you can see, it calls for a class called SignalSignature, so let's create it.

Create a new Swift file called SignalSignature.swift and add the following code:

Every time a new Signal is created, a unique signature is created with it. This ensures that signals are never duplicated. A SignalSignature object requires: a String key, which identifies a particular event, and might be something like API_CALL_RETURNED; and an AnyObject listener, which would be the class instance that wishes to listen for the API_CALL_RETURNED signal. Thus each SignalSignature ensures that each class instance can only listen once for any given type of signal.

Next add the following private function:

_getSignalBy( Key ) will return an existing Signal, or create one and then return it if it doesn't already exist and the parameter createIfMissing is true. Each and every signal is identified by a key - such as API_CALL_RETURNED mentioned just above - and can have multiple listeners listening to it.

Next add the following private function:

This function will be called by the public function addListenerFor( Key ). We could of course simply put the functionality for adding a listener in addListenerFor( Key ) itself, but should later we wish to have a function that adds multiple listeners, such as addListenersFor( Keys ), it would require refactoring, so it's good to take that into account upfront.

Next edit addListenerFor( Key ) to look like this:

Let's go through what happens here:

  1. If the listener requesting to be registered already exists, the registration attempt is blocked and false is returned;
  2. assuming that the request is new, we then get or create a Signal, and a SignalSignature;
  3. if the relevant collection of signatures does not already exist in the _signatures Dictionary, it created and set locally;
  4. the signature is set in said relevant collection of signatures;
  5. the signal itself starts listening via Signal's listen() function; and
  6. either true or false is returned, depending on success or otherwise.

At this point we can add a listener to a signal. Now lets add the functionality to remove one.

Next add the following private function:

_removeSignalFor( Key ) simply deletes a signal by nullifying its listeners, and then removing references to it in our dictionaries, all to be safe for memory management purposes.

Next add the following private function:

Every signal has the array property listeners, and _annulEmpty( Signal ) simple deletes any signal which has nothing left listening to it, by querying the count property of listeners. As you can see, it calls _removeSignalFor( Key ).

Next add the following private function:

As you can see, it calls _annulEmpty( Signal ). Let's go through what happens here:

  1. If we are trying to remove a non-existent listener, just block the call;
  2. Otherwise stop listening by just calling Signal's removeListener() function;
  3. Finally, assess whether this was the last listener this signal had, and if so delete it.

We are now in a position to remove listeners.

Add the following code to removeListenerFor( Key ):

This simply calls the private function _removeListenerFor( Key ). And as in the process of creating the functionality to remove listeners we created the private function _removeSignalFor( Key ), we are now also in a position to remove signals.

Add the following code to removeSignalFor( Key ):

This simply checks if we have a given signal, and if so deletes it. So that's listeners added and removed, and signals added. All that's left to do is dispatch a signal.

Add the following code to dispatchSignalFor( Key ):

Signals creator Tuomas Artman says only that => is a "special operator" which can be used to fire signals. I have not been able to find any more information on this special operator, more information would be gratefully received if you have any.

With those functions added the code is complete. Here is the full class without line breaks:

Introduction

In the following tutorial, we will build a sample iPhone app that initialises its Model and its View with Swinject, a Dependency Injection framework for Swift.

Swinject is a new, lightweight Dependency Injection (DI) framework for Swift, and this matters because:

  • there was only one DI tool available before Swinject: Typhoon; and
  • being older, Typhoon is larger, and more suited to Objective-C projects; but mainly because;
  • DI is an excellent way of safely defining scope within an application.

Put simply "dependency injection means giving an object its instance variables," as James Shore said in 2006. For more information on why this matters, and the importance of scope, try this Wikipedia article. Assuming you’re good with the concept of DI, let’s press on.

Protocols

With Swift 2.0, we are encouraged to use Protocol-Oriented Programming. Protocols are similar to Interfaces, which object-oriented programmers should be familar with. Essentially, a Swift protocol lists of functions that a given class should contain, or implement.

Here, a protocol called APIProtocol describes one method, call( URL ), which requires two String parameters: URL; and httpMethod, which any class which implements it must therefore have. For instance, both of the following classes implement APIProtocol, but similarly both would throw compile-time errors:

The former does not implement call( URL ) at all, whilst the latter declares httpMethod as an optional let, neither of which match the declaration in APIProtocol. The following is what we need.

Registering Protocols

Because it suits both DI and Swift, Swinject is built around the concept of protocols. It creates and injects instance variables by registering the abstract protocols that describe them - like APIProtocol above - with concrete instances that implement them - like APIService. Here's what that means in practice.

Container() is a class provided by Swinject, which handles DI registrations. Here, we are instantiating an instance of it, and then registering APIProtocol with it, with the instruction that when it is asked to create a new instance of APIProtocol, it will actually create an instance of APIService. Thereafter, we will instruct Swinject to create one or more instances of APIService for use in other classes, classes that presumably need to query the API.

That's the theory, now lets do some actual injecting!

Adding Swinject to your Project

Swinject itself first needs adding to your project via Cocoapods or Carthage.

Initialising Swinject

Swinject will take care of its own initialisation as long as you add the right class in the right way. In your project, create an empty Swift file called SwinjectStoryboard.swift and add the following code:

By extending Swinject's own SwinjectStoryboard class, and implementing the class function setup(), you will force Swinject into initialising your injectable properties for you. Next add the following:

The let container = Container() line under the header Registering Protocols we looked at above isn't strictly necessary. Swinject will have created a default Container for you, with the name defaultContainer, which I find a little too long, so shorten to swinject in order to avoid cluttering up my screen.

Registering Classes

Once we have access to this default container, we can use it to initialise our injectable properties:

Here we are referencing the APIService which implements the APIProtocol, which we mentioned earlier, and registering it with Swinject in the way we described earlier.

Registering Single Class Instances

With the above registration of APIService, every time an instance of APIService is injected, it will be a new, unique instance of it. But there is no need to have multiple gateways to our API, one will suffice, and Swinject allows the creation of singleton (with-a-small-s) instances with the simple addition of one line:

Singletons (with-a-capital-S) are controversial because of their global nature, and therefore best avoided for very good reasons. However, this implementation is singleton (with-a-small-s), which is not global, and therefore safe. What we are essentially telling Swinject is this:

  1. Don't make any instances of APIService;
  2. however, if any class asks for one, create a single instance of it, keep it in memory, and pass a reference to it to that class; and finally
  3. pass the same reference to any subsequent class that asks for its own instance of APIService.

If you are unsure about the difference between Singletons and singletons, and why the uppercase type should be avoided, I would strongly recommend you research them both.

Injecting Registered Class Instances

Here we introduce a second service, ImageService. As its name suggests, it is responsible for loading and serving images to its app. As part of its job, it needs to query the API, and so needs access to the single instance of APIService we registered immediately above. Swinject makes this simple, this time we give the property created in the register() method - which previously had the nameless underscore character - the name responder, and then use it to inject our single instance of APIService into a property within ImageService's init() method called api via responder's resolve() method.

Accepting Injected Registered Class Instances

ImageService, then, will need a way of accepting the api property it is passed, and this is how:

Thus, Swinject does the hard work of ensuring for us that only one instance of APIService is ever made, and that the self same instance is injected into any class instance that asks for it. For instance, we could now go on to add the following code:

An instance of LogService that now gets created will have an instance of APIService injected into it at initialisation, and crucially the same instance as that which will be injected into a new instance of ImageService. And as both LogService and ImageService utilise the line .inObjectScope( .Container ), they too will only be created as single instances, stored within Swinject.

Injecting Registered Class Instances into ViewControllers

Thus far we have only injected properties into Model type classes, but of course Swift apps are full of ViewControllers, which conceivably also need access to the API and the Logger and so forth. Naturally, Swinject has a method for this:

Swinject's registerForStoryboard() method accepts a ViewController prototype as its single argument, and then allows any formerly-registered classes to be injected into instances of it. However, ViewControllers accept Swinject injections via public properties and not init() methods. Here is what YourViewController.swift will have to look like:

Th implementation for ViewControllers is necessarily more complicated, involving computed properties, the write-once pattern, willSet, guard, etc. If you are not familiar with any of these techniques, I suggest you read up on them. Your-favoured-search-engine - whichever one it is - will help, I'm sure. The rationale behind using them is to ensure that each ViewController can have its injected properties injected just once, and that after having been injected they are private, and thus securely inaccessible to other parts of your app.

Given that these injected properties will not be available immediately, you will have to wait until the viewDidLoad() method is called, before referencing them:

drawing of a carrier bag
The still life medium developed from a Dutch mercantile tradition of displaying goods in an idealised manner. Therefore, drawing the ephemera of modern life in the same way is subversively rewarding, in a gentle way. The green plastic ex-mushroom container inside the bag shines through nicely.

As Paul Hudson explains, Swift function parameters have external and internal names, the external coming first. Any functions utilising two or more parameters must reference all parameters after the first by their names, the external name if one provided, the internal name if not. So the following functions:

Would be called like this:

The fact that the first parameter does not need to be named is a hangover from Objective-C, which is a euphemistic way of saying: suboptimal. Obviously, Apple would like to attract Objective-C programmers over to Swift, and so they provide such similarities to Objective-C to ease the transition. However, those of us coming to Swift directly - like me - do not approve of these inconsistencies. Clarity is an essential element of "swiftiness," and therefore, if one is passing a parameter to a function, one should be made to state and therefore know what that parameter is:

Both external and internal parameter names are given lowercase names, so that there isn't a weird and ugly inconsistency of function names starting with a lowercase letter, but parameter names starting with an uppercase one.

But, when we start applying this style to certain types of function - the "do-something-by-something" type - this starts to look weird and ugly in a different way:

"Height" is unnecessarily repeated. This is better:

Essentially, part of the function name appears inside the brackets. It may seem counterintuitive, but it's actually an elegant way around the inconsistency brought across from Objective-C. It works well for setters too:

Once you're used to function names like this, you can take this further, and use them everywhere. For instance, here's an actual function in one of my projects:

This does not currently form part of Ray Wenderlich's otherwise excellent Swift Style Guide, but I'm sure only because it hasn't occurred to anyone on their team yet. I hope they include it at a later date.

UPDATE

The release of Swift 3.0 has seen many changes similar to that made to NSDictionary's objectForKey function:

Following my comment about Ray Wenderlich's style guide immediately above - and given that I initially wrote this blog post in February of 2016 - I feel wholly vindicated in my belief that split function names are best practice.

Getter and setters - less commonly known as mutator methods - are as essential a part of Swift as they are of any modern language. But I find the verbs chosen to label them either inconsistent, or inaccurate, or both. "Set" is obviously chosen as it rhymes with "get," which is sensible enough, except that "get" itself isn't ideal in the first place. "Getting" something suggests the object is close at hand. Within the confines of an app, "getting" makes sense, but stepping beyond that seems inappropriate. Instead, I would suggest that the following makes sense, for different contexts:

Getting and setting locally remains fine. When deleting properties locally, they are almost always set to null, so annul is more accurate than delete. Likewise add and remove are sensible when referencing collections, and like get, gather starts with a "g," and implies retrieving multiple items. retrieve and store are reminiscent of household chores, and one's device is one's digital home, and delete suggests that it's gone, but not forever, assuming the data exists elsewhere. fetch and save are appropriate for data stored in databases as they suggest a certain distance to the data, and destroy really does underline that once a property stored in a database is deleted, it is gone forever. resolve underlines that when querying an API etc., one can never really know what one is going to get back: useful data; a successful flag; a network error. It's just impossible to know. So call an API via a function named something like resolve( Username ), and send the callback to a function named something like onUsernameResolved, where it's payload can be assessed.

I imagine there will be readers who find this pedantic, or some other flavour of pointless, phrases like GET are already enshrined in, say, query language traditions, so why change something that isn't broken? Two reasons:

  1. Tradition is bullshit. It was once traditional to pour one's faeces out of the window, but once we learned that was suboptimal, we stopped it; and
  2. when one starts a function with one of these verbs, because they are all different it shows the programmer immediately what manipulation that function is going to perform: it will get, set, or delete data - sure - but it is also clear where and how the manipulation will take place. The expressive strength of each verb increases with increasingly serious actions:

And if the style of the three functions listed immediately above seems strange to you, please see my post on splitting function names.

drawing of a fishing weight limestone
Sussex fishermen often collect pieces of limestone from the surrounding chalk hills, and drill holes in them so that they can be tied to nets as weights for their nets. Being a sedimentary rock, limestone is quite easy to drill through. Once these have met the end of their useful lifespan, they are often discarded on the local beaches, where people find them and wonder over the causes of the strange, smooth holes in them.