If you’re using a base class in Swift, you’re doing it wrong

Cut out repeated code from your view controllers

Image for post
Image for post

I noticed a curious thing. I had a UIActivityIndicatorView in every view, with a nice loading screen that can be added to the screen when we perform an animation or make an API call.

This meant one thing. Repeated code. Before copying and pasting my tests to every view controller I thought I’d do one thing. Make a base class. What a mistake.

Prerequisites:

  • Some basic understanding of OO
  • Some understanding of Swift

Terminology

Base class: A base class is a class from which other classes are derived.

Extensions: These add new functionality to an existing class, structure, enumeration, or protocol type within Swift

Creating a base class

The code

The following base view seemed to be what I wanted — create an indicator and remove it as necessary. It all seemed so simple

For each view controller I can then inherit from this subclass:

class MenuViewController: BaseViewController

Fantastic: job done.

The problem

I want to implement this same functionality in my UITableViewController. No problem — I’ll copy and paste into a new base class for UITableViewControllers, and then do the same for UICollectionView. No problem.

But you implemented this BaseViewController to cut out code duplication! Doh!

Worse: you’re not following the SOLID principles.

Image for post
Image for post

Now I want to extend UIViewController, but we have an issue with stored properties. That is, you can’t use stored properties in extensions, which kind of stops us coming up with a solution for having an indicator display that we can later remove. Setting a tag for the indicator is a fragile and not professional solution.

So how do we proceed?

The answer is using the Associated objects API (https://stackoverflow.com/questions/25426780/how-to-have-stored-properties-in-swift-the-same-way-i-had-on-objective-c)

The problem

We can use a helper class

and then refer to this within our extension:

Which can then match to a UIView

However, this will not suffice for adding the indicator to a UIWindow. Unfortunately this is similar code to the extension for the UIView, but still:

In either case this can be called with the following to start indicating and block the screen:

self.startIndicatingActivity()

To stop it we do the following:

self.stopIndicatingActivity()

and to add to the Window we need to define the window:

let window = UIApplication.shared.keyWindow!

window.startIndicatingActivity()

and

let window = UIApplication.shared.keyWindow!

window.startIndicatingActivity()

A full repo with the code? Ok: just this once, for you:

https://github.com/stevencurtis/StoredPropertiesInExtension

Any claps or follows are much appreciated. Want to get in contact? Use Twitter:

www.twitter.com/stevenpcurtis

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store