How to use Swift optionals

Last year Apple announced Swift. It came with a bundle of new features that were kind of unfamiliar to Objective-C developers. The most notable of these new concepts were optionals.

Swift optionals are a cornerstone feature in the language. They are nested deep inside Swift – basically everywhere you look. The thing is that they are not that hard to understand, but at the same time are difficult to master.

Sure, maybe you’ve learned how to use them, you might even have learned how to fix cryptic compiler errors related to them (if you have, you deserve applause). However, knowing how to use Swift optionals in “the real world” is a whole new thing.

Having written a certain amount of code, I definitely cannot say I know how to manage Swift optionals, but I have learned many things from experience. So what you are about read is not a definitive guide to using Swift optionals, but rather my take on them. I’ll be happy to get feedback from you if you think something I wrote is incorrect.

I’m writing this article because I feel that not much has been said about the proper way to use Swift optionals. It is my desire to at least start a discussion about it. So fee free to join in!

Problems that Swift optionals solve

In order to see how we can use Swift optionals, we first need to determine what problems they solve. For a detailed overview on what they are, please refer to my Swift optional values article.

Basically, Swift optionals replace nil from Objective-C. As you know, Cocoa is really tolerant when it comes to null objects. You can pass an empty pointer, even call a method on a nil object, without ever worrying that your application might crash. However, this is not always good. Consider this:

NSArray* myArray = [NSArray arrayWithObject:nil];

It crashed! Why? Because not every method in Cocoa can work with nil. Another example:

NSString* token = session.retrieveUserToken();
if (token == nil)
{
    // hmmm... now what?
}

The return value is nil. But what does that mean? Does it mean that the session object couldn’t get the token? Or maybe the token is just nil? And in general… is it OK for the token to be nil? Who knows…

The morale of the story is that there is no convention in Objective-C that distinguishes between an invalid object and no object at all.

Enforcing a convention about return values and parameters might not seem like a very big deal. However, when it comes to keeping code clean and easy to read, a little can come a long way. In my experience you really have to make developers write code in a certain way, otherwise they will slowly start drifting away and ignoring your rules.

When to use Swift optionals

This one is relatively easy. You use a Swift optional every time there is a chance that your variable might be nil. Also, most of the time the compiler will force you to apply this rule.

That being said, there are occasions where you might want to define a variable as optional when in reality you don’t need it to be. That can happen with parameter names. Even if you know you wont be needing an optional for the purpose of your method, you need to think about how you (and others) will be using it. Is it common for this function to be called in situations where the parameter names will be optionals? For example, a method that works with views inside a view controller will typically work with optionals since many of the ways to get a reference to a UIView object return an optional (IBOutlets, traversing the view hierarchy etc.). In such a method it would be really convenient to be able to pass an optional so that you don’t have to unwrap every time you call it.

? or !

A difficult decision when it comes to Swift optionals is choosing between normal and implicitly unwrapped optionals. As a newbie in Swift you might be tempted to use the latter in most cases just because it’s easier. In fact, many StackOverflow answers and blog posts suggest that. But that’s dangerous thing to do. Using implicitly unwrapped optionals is kind of like using:

NSArray* myArray = self.arrayFullOfWonders;
NSObject* firstWonder = [myArray objectAtIndex:0];

Yes, it should (theoretically) work, but you have to be REALLY certain that the array has at least one item. Otherwise, bad things will happen. It’s much better to write:

NSArray* myArray = self.arrayFullOfWonders;
NSObject* firstWonder = [myArray firstObject];

This code does the same exact thing as the previous. But it also doesn’t crash when the array is empty.

That’s exactly how I feel about Swift optionals. Using implicitly unwrapped optionals is a lot like objectAtIndex:. You have to be extremely suspicious about writing theat“!”. Use it only when you are absolutely, 200% sure that your variable is not nil. In all other cases, your the conventional optionals with “?”.

Designing with optionals in mind

The hardest aspect of Swift optionals is deciding how to use them in methods and classes that you are about to design and create. When using Cocoa classes, in most cases you are forced to use them in one way or another. A method either requires an optional or not. However, when you are the one designing that method, it can get a little more complex.

First of all, you need to decide whether or not your method parameters and return value should be optionals. For the return value this is easy – you return an optional whenever it is acceptable to return nil and a regular variable when you can guarantee that an object can be returned.

Parameter names can be a little bit trickier. It is easiest to just declare them as non-optionals so that your method body gets simpler. However, this is a silly way to go. There are cases where having a nil parameter is perfectly fine semantically. If your method signature does not allow them, you are missing values from your input domain. So, it really pays to stop and think about it for a second. Is it acceptable that some of my parameters are nil? This is an useful question even outside the scope of Swift optionals and it can lead to better design and spare you a few bugs later on.

Even if it’s not strictly valid for your parameter to be nil, it can still be useful to make them optional. As I hinted in one of the previous paragraphs, it can help you (and others) when using the method you are designing.

Think about how your code will be used. Will it be used with data that is mostly optional. If it’s so, it might prove useful to make it “optional friendly”. Instead of making the people using your code constantly unwrap optionals just to invoke your method, you might start using optionals yourself. It can make people’s code a lot simpler.

Of course, you shouldn’t make your parameters optionals just because it would be more convenient when using the method if that contradicts with its… uhm… philosophy.
If you feel like a method shouldn’t be accepting optional parameters, then just don’t do it. However, there are many situations where it doesn’t really matter.

When you’re working with views, for example, having optionals is not a big deal. Most of the things you can do with UIView can be also done transparently with an optional UIView:

controlsView?.hidden = true

Here, we don’t really care if controlsView is nil or not. We just want to hide it. If it isn’t there (maybe it’s not yet allocated), the method call will just do nothing and execution will continue without any changes. Even if this wasn’t the case, we could have unwrapped the optional before doing anything to it:

func hideCnntrolsView(controlsView:UIView?) {
    if let controlsView = controlsView {
        controlsView.hidden = true
    }
}

Methods like this can work with both optionals and non-optionals without too much trouble. So if they will be used around many optional variables, it might make sense to make them “optionals-ready”.

To summarize, these are the basic rules I personally follow when making Swift optionals related decisions:

  • If it is possible that I variable is nil, use an optional
  • When using frameworks, always follow the API’s convention
  • Be very suspicious about implicitly unwrapped optionals. Use them only when:
    • You are ABSOLUTELY sure the variable will NEVER contain nil
    • For IBOutlets (if a non nil value cannot be parsed from the Xib, an exception will be thrown either way, so it is safe to assume the variable contains a real object)
    • For member variables that cannot be initialized in the constructor, but are guaranteed to receive a value elsewhere in the code
      • For example, if the variable is assigned in a view controller’s viewDidLoad method
  • Prefer non-optional parameters, but don’t hesitate to use them if nil parameters are a valid use case
  • You can make a parameter optional if that will make it’s usage easier as long as it does not conflict with the method’s “philosophy”.

Swift dictionaries

This post is part of a Swift vs Objective-C series where we look at new features in Swift and how they compare to their predecesors from Objective-C.
In this article, we are going to discuss Swift dictionaries.

Make sure to also visit the article about Swift arrays.

Whats new with Swift dictionaries and arrays?

I kind of liked NSArray and NSDictionary, to be honest. I thought that they are easy to use and powerful. That’s why I was a little disappointed to learn that Swift changed them so dramatically. Admittedly, collections in Objective-C are more suited to the “power user” – there are really amazing things they can do. But that comes at a price. It can be really easy to lose track of how you’re using them and end up with messy code.

Apple’s engineers re-envisioned Swift dictionaries by introducing a lot more restrictions and not allowing developers to go crazy with them.

Swift dictionaries and arrays eliminate primitive obsession

One of the major errors Swift dictionaries (and arrays) prevent, is Primitive Obsession. Primitive obsession refers to a code smell that involves using primitive data types when you should really have a custom class that holds your data. Many times, in Objective-C this means storing a bundle of related but not homogeneous pieces of information in an array or dictionary. For instance, if you need to store a collection of username and password pairs, you might be tempted to allocate two arrays, one containing usernames and the other passwords, or maybe having an array of dictionaries, each containing a username and password keys. This might be the first thing that comes to mind, but it’s really not a good idea. The right choice would be to create an Account class that contains properties for the information your application requires.

Since Swift dictionaries can only contain data with the same type (only strings or only numbers, for instance), developers have no choice but to use collections in a way that is easy to understand and maintain.

That being said, I have to say that Swift dictionaries are a leap forward for the iOS development community. But I’ll probably miss NSDictionary.

Swift dictionaries contain objects of the same type

Swift does not allow you to add different types of data in the same collection. When you create it, you have to specify what kind of data you intend to store. Of course, the compiler uses type inference to guess the data type if you omit it. From then on, if you try to add an object from another class to your dictionary, a compile time error will be raised.

Swift dictionaries mutability

In Objective-C, NSDictionary is immutable. If you needed to change a collection at runtime, you needed to use it’s counterpart – NSMutableDictionary. With Swift dictionaries, there is a more general solution to this problem. And it also works for strings, arrays and other primitive data. Mutability is controlled by the variable itself – a var is mutable, whereas a let is immutable.

let myDict:Dictionary<String, String> = [“Swift”: “language”, “Array” : “Collection”, “Dictionary”: “Collection”]
myDict.removeValueForKey(“Swift”)

This code generates the following error – “Immutable value of type ‘Dictionary<String, String>’ only has mutating members called ‘removeValueForKey'”. Descriptive as always…
However, if we declare myDict as a variable and not a constant, the code will work:

var myDict:Dictionary<String, String> = [“Swift”: “language”, “Array” : “Collection”, “Dictionary”: “Collection”]
myDict.removeValueForKey(“Swift”)

After that statement, myDict contains ["Array" : "Collection", "Dictionary": "Collection"]

The synthax of Swift dictionaries

Creating a dictionary

let myDict:Dictionary<Int, String> = [1: “One”, 2: “Two”]
let myDictShort:[Int: String] = [1: “One”, 2: “Two”]
let myDictShorter = [1: “One”, 2: “Two”]

The first statement is the longest definition of a dictionary. The second one is a shorthand version of the first, and it’s prefered. The third definition just uses type inference to omit the data type.

Accessing members

Accessing dictionary members is almost the same as accessing array elements. In fact, an array might be thought of like a dictionary where the keys are the numbers from 0 to N, where N is the size of the array.

var myDict2 = [“One”: 1, “Two”: 2]
let element = myDict2[“One”]
let noElement = myDict2[“false Key”] // returns nil – no such element
myDict2[“Three”] = 3
myDict2.updateValue(4, forKey: “Three”)
myDict2.removeValueForKey(“Three”)

Iterating dictionaries

In Objective-C, iterating over all dictionary entries was a little more difficult than it should have been. In Swift, it is a lot easier due to tuples:

for (number, numberString) in myDict2 {
print(number)
println(numberString)
}

Each time execution goes in the loop’s body, the tuple is filled with a different pair taken from the dictionary. The (number, numberString) statement “parses” the tuple into the number and numberString variables so they can be used inside the loop. It’s short trick that allows you to write simple for loops.

Swift arrays

This post is part of a Swift vs Objective-C series where we look at new features in Swift and how they compare to their predecesors from Objective-C.
In this article, we are going to discuss Swift arrays and dictionaries.

Make sure to also visit the article about Swift dictionaries.

Whats new with Swift arrays and dictionaries?

I kind of liked NSArray and NSDictionary, to be honest. I thought that they are easy to use and powerful. That’s why I was a little disappointed to learn that Swift changed them so dramatically. Admittedly, collections in Objective-C are more suited to the “power user” – there are really amazing things they can do. But that comes at a price. It can be really easy to lose track of how you’re using them and end up with messy code.

Apple’s engineers re-envisioned Swift arrays by introducing a lot more restrictions and not allowing developers to go crazy with them.

Swift arrays and dicitonaries eliminate primitive obsession

One of the major errors Swift arrays and dictionaries prevent, is Primitive Obsession. Primitive obsession refers to a code smell that involves using primitive data types when you should really have a custom class that holds your data. Many times, in Objective-C this means storing a bundle of related but not homogeneous pieces of information in an array or dictionary. For instance, if you need to store a collection of username and password pairs, you might be tempted to allocate two arrays, one containing usernames and the other passwords, or maybe having an array of dictionaries, each containing a username and password keys. This might be the first thing that comes to mind, but it’s really not a good idea. The right choice would be to create an Account class that contains properties for the information your application requires.

Since Swift arrays can only contain data with the same type (only strings or only numbers, for instance), developers have no choice but to use collections in a way that is easy to understand and maintain.

That being said, I have to say that Swift arrays are a leap forward for the iOS development community. But I’ll probably miss NSArray.

Swift arrays contain objects of the same type

Swift does not allow you to add different types of data in the same collection. When you create it, you have to specify what kind of data you intend to store. Of course, the compiler uses type inference to guess the data type if you omit it. From then on, if you try to add an object from another class to your array, a compile time error will be raised.

Swift arrays mutability

In Objective-C, NSArray is immutable. If you needed to change a collection at runtime, you needed to use it’s counterpart – NSMutableArray. In Swift, there is a more general solution to this problem. And it also works for strings, dictionaries and other primitive data. Mutability is controlled by the variable itself – a var is mutable, whereas a let is immutable.

let myArray:Array<String> = ["Swift", "Array", "Dictionary"]
myArray.append("Collection")

This code generates the following error – “Immutable value of type ‘Array‘ only has mutating members called ‘append'”. Descriptive as always…
However, if we declare myArray as a variable and not a constant, the code will work:

var myArray:Array<String> = ["Swift", "Array", "Dictionary"]
myArray.append("Collection")

After that statement, myArray contains ["Swift", "Array", "Dictionary", "Collection"]

The synthax of Swift arrays

Creating Swift arrays

let myArray:Array<String> = ["Swift", "Array", "Dictionary"]
let myArray = ["Swift", "Array", "Dictionary"]  // type inference allows you to omit the type of the variable 

As you can see, Swift uses the same synthax for array literals that Objective-C introduced in it’s most recent versions.

Accessing and modifying array values

There are many ways to do that and most, if not all, you might remember from Objective-C

let firstElement = myArray[0]
let myArray = ["Swift", "Array", "Dictionary"]  // ["Swift", "Array", "Dictionary"]
myArray.append("Last item") // ["Swift", "Array", "Dictionary", "Last item"]
myArray += ["Last item 2"]  // ["Swift", "Array", "Dictionary", "Last item", "Last item 2"]
myArray.removeLast()        // ["Swift", "Array", "Dictionary", "Last item"]
myArray.removeAtIndex(0)    // ["Array", "Dictionary", "Last item"]
myArray[0] = "First"        // ["First", "Dictionary", "Last item"]

Note: Accessing or modifying an element beyond the array’s bounds will raise an exception:

myArray[13] = "13"    // raises an exception because 13 is beyond the arrays bounds
let element13 = myArray[13] // also raises an exception

Iterating arrays

Iterating Swift arrays is almost the same as in Objective-C:

for string in myArray {
    print(string)
} 

This code will print out every member of the array.

Swift Closures

This post is part of a Swift vs Objective-C series where we look at new features in Swift and how they compare to their predecesors from Objective-C. In this article, we are going to discuss Swift closures.

What are Swift closures?

Depends who’s asking…
To an Objective-C developer, a closure is Swift’s equivilent of blocks.
A formal definition should be that Swift closures are self-contained blocks of functionality
Intuitively, a closure is a kind of anonymous, nested functions. It’s a chunk of functionality that you can pass around in functions and variables.

In reality, closures and blocks do little more than provide a more convinient way of encapsulating functionality than nested fuctions and function pointers. Despite that, in the past couple of years, there has been a massive effort to integrate blocks into our Objective-C code.

Swift closures synthax

Swift closures closely resemble Objective-C (or any other language, supporting them) blocks. To define one, you’d write something like this:

{ (parameters) -> return_type in
    // block body
    // write code here
}

This is longest, most formal way of creating Swift closures. As with all languages influenced by functional programming, there are many shorter versions, which we will cover shortly.

Closures as function parameters

Let’s face it, you are most likely to use Swift closures as parameters. Let’s take a look at some specifics to doing that.
First of all, it is important to know how to define a function that takes swift closures as one of it’s parameters:

func calculateSomething(something1:Float, something2:Float, calculator:(value1:Float, value2:Float) ->Float) ->Float {
    return calculator(value1: something1, value2: something2)
}

I hope there is nothing disturbing in this statement to you. It’s a function that takes three parameters – two floating point numbers and another one called calculator. When we inspect it’s type, we will discover that it’s not a basic data type or a class. It’s a function signature, specifying what parameters the closure takes and what value it returns.

Now, to use the calculateSomething function, we can do the following:

calculateSomething(23.76, 125, {(value1:Float, value2:Float)->Float in 
    return value1 + value2
})

Written like this, the function is calculating sums. As you can see, we supplied two numbers and a closure that is essentially a very complicated + operator. However, as with most “functional” languages, that is simply too long to write. Life is too short to write swift closures with the full synthax. That’s why there are shorter versions of this statement.

calculateSomething(23.76, 125, {(value1:Float, value2:Float) in 
    return value1 + value2
})

Type inference to the rescue! Since the compiler already knows the signature needed for this function call, it can “guess” what a suitable closure would look like. That’s why we can skip explicitly specifying it’s return type. You might wonder if the same is true about the parameter’s type. Well, it is…

calculateSomething(23.76, 125, {(value1, value2) in 
    return value1 + value2
})

All data types can be inferred from the function definition.
While we are at it, we can also omit the parenthesis:

calculateSomething(23.76, 125, {value1, value2 in 
    return value1 + value2
})

Next, we can continue with the closure’s body. In swift, you can omit the return keyword for functions that have only one statement. Since this is the case in our example, we can shorten our code even more:

calculateSomething(23.76, 125, {value1, value2 in 
    value1 + value2
})

But wait, there’s more! Here’s an interesting little feature from scripting languages. You might know (from Bash for instance) that you can access function and script paramenters using the $ synthax (like $0, $5, $8). So…

calculateSomething(23.76, 125, {
    $0 + $1
})

Note that inlike Bash, where $0 is the path to the script being executed, in Swift it is actually the first parameter.

Pretty nice, eh? Our function call got a lot shorter. Of cource, this is just synthax sugar. It doesn’t add any expressive power to swift closures – it just makes them more convenient to write and read.

As a bonus for being so patient, here’s one final short form. Since the closure we were using sums two numbers, which is exactly what + does… we might as well use that operator:

calculateSomething(5.0, 12.6, +)

Yes, that’s a thing in Swift.

Variables of type closure

Sometimes, it can prove useful to store swift closures in a variable. So, let’s briefly talk about that.

let closureVar = {(value1:Float, value2:Float)->Float in 
    return value1 + value2
}

By now, you should be comfortable with this synthax. It’s not much different than what we looked at above. Though, it looks like a long this to write. It almost makes you not want to use that variable. Can’t we use something shorter, like we did last time?

let closureVar2 = {(value1, value2) in 
    return value1 + value2
}

It doesn’t work ;(. Why? Well, we can omit the parameter data types and return value only if the compiler can infer them from the context. And since we didn’t specify the closureVar2‘s type, Swift doesn’t know the closure’s signature that it should expect.

let closureVar3:(value1:Float, value2:Float) ->Float = {(value1, value2) in 
    return value1 + value2
}

Explicitly adding a type to our variable solves that problem, but our statement is no longer that short.

Now that we have a variable containing our closure, we can use it in all situations a closure is needed. Like in all examples from the previous paragraph:

calculateSomething(5.0, 12.6, closureVar)

Capturing values

This section contains some general information about capturing values. If you are familiar this concept from Objective-C’s blocks, feel free to skip the following paragraph.

Everything up until now is not that impressive to be honest. Being able to store functions in a variable and use them as parameters is a standard feature of most languages. What makes Swift closures (also blocks and lambda functions in Objective-C and other languages) so popular, is capturing values. The concept is rather simple. Unlike conventional function that operate in a sort of a vaccum, closures have the ability to use variables defined in the code block enclosing them. Let look at an example:

func myFunction() {
    var funcVariable = 15
    let closureVar: () = {() -> () in
        // This closure will be able to access variables 
        // from the function it was defined from -
        // funcVariable for instance
        var closureVariable = funcVariable
        funcVariable = 25
        }()
    closureVar
    print(funcVariable)
    // funcVariable is now 25
}

The outer function myFunction creates a local variable funcVariable. After that it defines a closure, which is able to use that local variable and even change it. Actually it has a reference to it so that if the value is modified within the closure, the new value doesn’t get lost as soon as the code block ends.

Retain cycles with Swift closures

Capturing values is a pretty useful feature. However, there are some things to be careful with. As the title suggests, they are related to retain cycles. Since the closure has to make sure all local variables that it needs from it’s container are readily available within it’s body, it retains them. It is possible that an object retains a closure, and that same object is used within the closure’s body, meaning that they both keep each other “alive”. Most often this happens when a class has a closure as a member variable and that same closure uses self within it’s body. In such cases, the object retains the closure, which in turn retains the object of the class.

Retain cycles like these are relatively hard to track because they are very subtle. And with ARC, things are getting even worse as most developers lose the habbit of thinking about memory management.

Custom UIPageViewController

The traditional UIPageViewController

A few months ago, I wrote an article about using UIPageViewController. I even wrote about dynamically exchanging view controllers inside of it. However, I am a bit embarraced to admit that, even though the code I used there works, I don’t actually use it for my projects. Shortly after I posted that tutorial, I realized that it is too problematic and decided to write my own custom UIPageViewController. Ever since, I’ve felt I needed to post another tutorial to let my readers know that there is a better way to dynamically change pages.

Anyway, if you feel that you still want to try the conventional UIPageViewController (which is perfectly fine in most cases), you might want to go read my UIPageViewController tutorial article.

Why should you use a custom UIPageViewController

As I said, using a UIPageViewController is perfectly fine in most cases. In fact, It’s a fantastic class that is both excellent for user experience and easy to use. However, since it relies on a data source to provide it’s “pages” and it also enforces a caching policy to ensure smooth scrolling and avoid unnecessary creation of view controllers, it can get a bit hard to dynamically insert and remove pages. In the UIPageViewController turotial article I wrote how you could force it to clear it’s cache, allowing you to exchange controllers, but I found that even then there are problems (and by problems I mean crashes).

It was then that I realized that it was nothing more than a UIScrollView with paging enabled and having each page as a child view controller. It shouldn’t be that difficult to write a custom UIPageViewController. So I did…

DynamicPageViewController – a custom UIPageViewController

DynamicPageViewController is a class that mimics the bahavior of UIPageViewController, but also allows you to insert and remove pages on demand (even if you want to remove the currently displayed one). It relies on an UIScrollView to layout it’s views and support a pan gesture to turn pages.

It’s interface is rather simple. It maintains a viewControllers property that holds all view controllers that represent pages in the custom UIPageController. If you modify that array, the views will automatically be redrawn to refrect the change.

Also, you can use the insertPage and removePage methods in order to change the layout.

func insertPage(viewController: UIViewController, atIndex index: Int)
func removePage(viewController: UIViewController)

To summarize, these are the only items in DynamicPageViewController’s interface you would generally care about:

  • viewControllers property (maintains an array of currently displayed pages)
  • insertPage method
  • removePage method

Without further ado… the custom UIPageViewController – DynamicPageViewController. In order to be in line with the latest fashion, it’s written in Swift, but it shouldn’t be that difficult to port to Objective-C, if that’s what you need. it is released with an MIT license and is freely available for download in github.
Enjoy!

NOTE: An MIT license means that you will be able to use it without restriction in your projects (free or commercial) without disclosing who wrote it