Swift – Singletons

Singleton and the TodoManager

The goal of the current project is to create a Todo App. This app will work with Todo items that need to be shared across more than one view controller. One approach is to create a single instance of a class that can be shared across the entire app. This is called a Singleton.

What is an instance?

A class file describes a type of object that can be created from that class. Each Object created from a class is called an Instance. For example our app will store Todo items. These are defined in the Todo class.

class Todo {

}

A class will define the properties, and methods of an object, and include an initializer.

class Todo {
var name: String
var completed = false
init(name: String) {
self.name = name
}
}

Create an instance of a class by using the name of the class like this.

var somethingTodo = Todo(name: “Eat Breakfast”)

In this case somethingTodo is an object with properties of name, and completed.

Each time you use Todo(name: “”) you are creating a new instance of Todo. Each instance stores it’s own unique values for name and completed.

This method works well for Todo items since we want to create a new and unique entry each time we create a Todo.

TodoManager
If our app contains a list of todos, we need to make these available across multiple View Controllers. If the Todos are stored in an array that belongs to (is a property of) One View Controller it’s very awkward to make todos available to other view controllers.

A better approach is to create a separate class to manage the list of todos. This class will be responsible for holding the list of Todos, relaying the count of todos, adding new todos, deleting todos, etc.

Keeping all of the code that manages Todos in one class helps keep our code organized. All of the methods and properties that manage our list of todo items will be in one place. Imagine the TodoManage class looks something like this:

class TodoManager {
var todos = [Todo]()
var count: Int {
get {
return todos.count
}
}
func addNewTodo(name: String) {

}
func getTodoAtIndex(index: Int) -> Todo {

}
}

There is one problem. Imagine we have three view controllers:

ListTodoViewController
AddNewTodoViewController
TodoDetailsViewController

Now imagine that each of these creates a new instance of TodoManager:

Here each view controller has it’s own instance of a TodoManager. That’s three unique managers. This won’t work for our app. Imagine that the app adds a new Todo to the manager owned by AddNewTodoManager. The todos array in List, and Details would not be updated to match.

What we need to create is something that looks like this:

Imagine in this arrangement that each ViewController has a manager property that points to the same instance. Now List View controller is displaying the same list of todos that Add new and details are working with.

Really what we will create is something that will look more like this:

Imagine here that TodoManager owns an instance of itself, and other classes can access that instance.

Singletons and Shared instance
Singleton is the name of a software design pattern. A design pattern is a standard solution for common programming problems. Our todo app is trying to solve a standard software problem: we need single instance of a class that can be shared.

Static/Class properties
Normally classes will only use instance properties. In the case of the Todo class, name and completed are instance properties. Instance properties belong to each instance, and each instance stores it’s own unique values for these properties.

Classes can also define static properties. These properties belong to the class, not to each instance! here’s an example class:

class Test {
static var name = “Hello World”
var number = 10
}

The first property is static, and belongs to the class, while the second property is an instance property, which each instance will have.

Test.name // “Hello World”
var instanceOfTest = Test()
instanceOfTest.number // 10

Working with a singleton
The singleton pattern works like this, we’ll use the TodoManager as an example. This class wants to manager a list of Todos that it can share with other classes in our app.

The TodoManager class starts like this:

class TodoManager {
static let sharedInstance = TodoManager()

private init() {

}
}

Notice the property sharedInstance is static. This makes it a class property. You’ll access it with:

TodoManager.sharedInstance

This property is also a constant, let. This means it can only have one value. You can’t set change its value once set.

To complete the pattern we mark the initializer: init() with private. This means that this method is only accessible within this class. You won’t be able to access the initializer from outside of the class.

 

Swift – Structs

If you haven’t heard Swift is a new language from Apple. Swift aims to be a modern language that streamlines your work.

Swift is strongly typed. This means that every value in Swift must be assigned a type.

Here I would like to talk about one feature in Swift called Structs. Struct is short for Structure or Construct. A Struct is similar to an Object in JavaScript.

In Swift a Struct is value. You can think of it as a complex value. If you were to think of a typical value, in a variable you might think:

var x = 230

Here you have a single name, x, representing a single value the number (Int) 230. A Struct is the same, with the difference that a Struct is a structure containing more than a single value. You can think of the difference conceptually as the difference between: nail, and house. Nail is a single discrete element, while a house is single structure, it contains many sub elements.


var nail = 1
struct House {
    var nails = 23000
    var boards = 1200
}

You can see the variable nail holds a single value, while the house has two values: nails, and boards, and could contain any number of other values, like doors, switches outlets etc. Think of a Struct as a way to define an element that contains a group of related values. Imagine everything in your house as a struct:

struct House {
    var nails = 1000
    var boards = 200
    var lightSwitches = 4
    var doors = 3
    var sink = 1
    var toilet = 1
}

var myHouse = House()
println(myHouse.boards)

Structs can also contain functions. In many ways a Struct is similar to a class. From our perspective they act in very much the same ways. Internally the software works them. Structs are assigned as values and Objects created from a Class are assigned as reference.

Copy vs Reference

When assigning a value (this would be how Structs are passed around) the computer creates a copy of the Struct. When you assign an Object you are assigning a reference to the original Object. In short:

Structs are always copied when they are assigned.

Class Objects are not copied when they assigned.

For example:


struct House {
    var address = "123 Maple St."
}

var a = House()
var b = a 
b.address = "321 Elm St."

println(a.address) // prints 123 Maple St.
println(b.address) // prints 321 Elm St.

Here you have two separate Houses. The first (a) would have the address 123, the second would have the address 321.

Here’s what would happen with a Class


class House {
    var address = "123 Maple St"
}

var a = House()
var b = a 
b.address = "321 Elm St."

println(a.address) // prints 321 Elm St.
println(b.address) // prints 321 Elm St.

You have two references to the same house, which moved from it’s original address to the 321 address.

Here is what Apple has to say about structs: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html