Book Image

Swift: Developing iOS Applications

By : Jon Hoffman, Andrew J Wagner, Giordano Scalzo
Book Image

Swift: Developing iOS Applications

By: Jon Hoffman, Andrew J Wagner, Giordano Scalzo

Overview of this book

The Swift––Developing iOS Applications course will take you on a journey to become an efficient iOS and OS X developer, with the latest trending topic in town. Right from the basics to the advanced level topics, this course would cover everything in detail. We’ll embark our journey by dividing the learning path into four modules. Each of these modules are a mini course in their own right; and as you complete each one, you’ll gain key skills and be ready for the material in the next module. The first module is like a step-by-step guide to programming in Swift 2. Each topic is separated into compressible sections that are full of practical examples and easy-to-understand explanations. Each section builds on the previous topics, so you can develop a proficient and comprehensive understanding of app development in Swift 2. By the end of this module, you’ll have a basic understanding of Swift 2 and its functionalities. The second module will be the an easy-to-follow guide filled with tutorials to show you how to build real-world apps. The difficulty and complexity level increases chapter by chapter. Each chapter is dedicated to build a new app, beginning from a basic and unstyled app through to a full 3D game. The last two chapters show you how to build a complete client-server e-commerce app right from scratch. By the end of these modules, you’ll be able to build well-designed apps, effectively use AutoLayout, develop videogames, and build server apps. The third and the last module of our course will take an example-based approach where each concept covered is supported by example code to not only give you a good understanding of the concept, but also to demonstrate how to properly implement it.
Table of Contents (6 chapters)
4
A. Biblography
5
Index

As we discussed in Chapter 2, Building Blocks – Variables, Collections, and Flow Control, all variables and constants must always have a value before they are used. This is a great safety feature because it prevents you from creating a scenario where you forget to give a variable an initial value. It may make sense for some number variables, such as the number of sandwiches ordered to start at zero, but it doesn't make sense for all variables. For example, the number of bowling pins standing should start at 10, not zero. In Swift, the compiler forces you to decide what the variable should start at, instead of providing a default value that could be incorrect.

However, there are other scenarios where you will have to represent the complete absence of a value. A great example is if you have a dictionary of word definitions and you try to lookup a word that isn't in the dictionary. Normally, this will return a String, so you could potentially return an empty String, but what if you also need to represent the idea that a word exists without a definition? Also, for another programmer who is using your dictionary, it will not be immediately obvious what will happen when they look up a word that doesn't exist. To satisfy this need to represent the absence of a value, Swift has a special type called an optional.

In this chapter, we will cover the following topics:

So we know that the purpose of optionals in Swift is to allow the representation of the absence of a value, but what does that look like and how does it work? An optional is a special type that can "wrap" any other type. This means that you can make an optional String, optional Array, and so on. You can do this by adding a question mark (?) to the type name, as shown:

Note that this code does not specify any initial values. This is because all optionals, by default, are set to no value at all. If we want to provide an initial value we can do so similar to any other variable:

Also, note that if we left out the type specification (: Int?), possibleInt would be inferred to be of type Int instead of an optional Int.

Now, it is pretty verbose to say that a variable lacks a value. Instead, if an optional lacks a variable, we say it is nil. So both possibleString and possibleArray are nil, while possibleInt is 10. However, possibleInt is not truly 10. It is still wrapped in an optional.

You can see all the forms a variable can take by putting the following code into a playground:

As you can see, actualInt prints out just as we expected, but possibleInt prints out as an optional that contains the value 10 instead of just 10. This is a very important distinction because an optional cannot be used as the value it is wrapping. nilInt just reports that it is nil. At any point, you can update the value within an optional; this includes assigning it a value for the first time, using the assignment operator (=):

You can even remove the value within an optional by assigning it to nil:

So we have this wrapped form of a variable that may or may not contain a value. What do we do if we need to access the value within an optional? The answer is that we must unwrap it.

There are multiple ways to unwrap an optional. All of them essentially assert that there is truly a value within the optional. This is a wonderful safety feature of Swift. The compiler forces you to consider the possibility that an optional lacks any value at all. In other languages, this is a very commonly overlooked scenario that can cause obscure bugs.

The safest way to unwrap an optional is to use something called optional binding. With this technique, you can assign a temporary constant or variable to the value contained within the optional. This process is contained within an if statement, so that you can use an else statement when there is no value. Optional binding looks similar to the following code:

An optional binding is distinguished from an if statement primarily by the if let syntax. Semantically, this code is saying, "if you can let the constant string be equal to the value within possibleString, print out its value; otherwise, print that it has no value." The primary purpose of an optional binding is to create a temporary constant that is the normal (non-optional) version of the optional.

We can also use a temporary variable in an optional binding:

Note that an asterisk (*) is used for multiplication in Swift. You should also notice something important about this code. If you put it into a playground, even though we multiplied the actualInt by 2, the value within the optional does not change. When we print out possibleInt later, the value is still Optional(10). This is because even though we made actualInt a variable (otherwise known as mutable), it is simply a temporary copy of the value within possibleInt. No matter what we do with actualInt, nothing will get changed about the value within possibleInt. If we have to update the actual value stored within possibleInt, we simply assign possibleInt to actualInt after we are done modifying it:

Now, the value wrapped inside possibleInt has actually been updated.

A common scenario that you will probably come across is the need to unwrap multiple optional values. One option is to simply nest the optional bindings:

However, this can be a pain, as it increases the indentation level each time to keep the code organized. Instead, you can actually list multiple optional bindings into a single statement separated by commas:

This generally produces more readable code.

Another great way to do a concise optional binding within functions is to use the guard statement. This way, you can do a series of unwrapping without increasing the indent level of the code at all:

This construct allows us to access the unwrapped values after the guard statement, because the guard statement guarantees that we would have exited the function before reaching that code, if the optional value was nil.

This way of unwrapping is great, but saying that optional binding is the safest way to access the value within an optional, implies that there is an unsafe way to unwrap an optional. This way is called forced unwrapping.

The shortest way to unwrap an optional is to use forced unwrapping. It is done using an exclamation mark (!) after the variable name when being used:

However, the reason it is considered unsafe is that your entire program will crash if you try to unwrap an optional that is currently nil:

The complete error you get is unexpectedly found nil while unwrapping an optional value. This is because the forced unwrapping is essentially your personal guarantee that the optional truly does hold a value. That is why it is called "forced".

Therefore, forced unwrapping should be used in limited circumstances. It should never be used just to shorten up the code. Instead, it should only be used when you can guarantee from the structure of the code that it cannot be nil, even though it is defined as an optional. Even in that case, you should see if it is possible to use a non-optional variable instead. The only other place you may use it is if your program truly could not recover from an optional being nil. In those circumstances, you should at least consider presenting an error to the user, which is always better than simply having your program crash.

An example of a scenario where it may be used effectively is with lazily calculated values. A lazily calculated value is the one that is not created until the first time it is accessed. To illustrate this, let's consider a hypothetical class that represents a file system directory. It will have a property listing its contents that is lazily calculated. The code will look similar to the following code:

Here, we have defined a superclass called FileSystemItem that both File and Directory inherit from. The content of a directory is a list of FileSystemItem. We define contents as a calculated variable and store the real value within the realContents property. The calculated property checks if there is a value loaded for realContents; if there isn't, it loads the contents and puts them into the realContents property. Based on this logic, we know for 100% certainty that there will be a value within realContents by the time we get to the return statement, so it is perfectly safe to use forced unwrapping.

Optional binding

The

safest way to unwrap an optional is to use something called optional binding. With this technique, you can assign a temporary constant or variable to the value contained within the optional. This process is contained within an if statement, so that you can use an else statement when there is no value. Optional binding looks similar to the following code:

An optional binding is distinguished from an if statement primarily by the if let syntax. Semantically, this code is saying, "if you can let the constant string be equal to the value within possibleString, print out its value; otherwise, print that it has no value." The primary purpose of an optional binding is to create a temporary constant that is the normal (non-optional) version of the optional.

We can also use a temporary variable in an optional binding:

Note that an asterisk (*) is used for multiplication in Swift. You should also notice something important about this code. If you put it into a playground, even though we multiplied the actualInt by 2, the value within the optional does not change. When we print out possibleInt later, the value is still Optional(10). This is because even though we made actualInt a variable (otherwise known as mutable), it is simply a temporary copy of the value within possibleInt. No matter what we do with actualInt, nothing will get changed about the value within possibleInt. If we have to update the actual value stored within possibleInt, we simply assign possibleInt to actualInt after we are done modifying it:

Now, the value wrapped inside possibleInt has actually been updated.

A common scenario that you will probably come across is the need to unwrap multiple optional values. One option is to simply nest the optional bindings:

However, this can be a pain, as it increases the indentation level each time to keep the code organized. Instead, you can actually list multiple optional bindings into a single statement separated by commas:

This generally produces more readable code.

Another great way to do a concise optional binding within functions is to use the guard statement. This way, you can do a series of unwrapping without increasing the indent level of the code at all:

This construct allows us to access the unwrapped values after the guard statement, because the guard statement guarantees that we would have exited the function before reaching that code, if the optional value was nil.

This way of unwrapping is great, but saying that optional binding is the safest way to access the value within an optional, implies that there is an unsafe way to unwrap an optional. This way is called forced unwrapping.

The shortest way to unwrap an optional is to use forced unwrapping. It is done using an exclamation mark (!) after the variable name when being used:

However, the reason it is considered unsafe is that your entire program will crash if you try to unwrap an optional that is currently nil:

The complete error you get is unexpectedly found nil while unwrapping an optional value. This is because the forced unwrapping is essentially your personal guarantee that the optional truly does hold a value. That is why it is called "forced".

Therefore, forced unwrapping should be used in limited circumstances. It should never be used just to shorten up the code. Instead, it should only be used when you can guarantee from the structure of the code that it cannot be nil, even though it is defined as an optional. Even in that case, you should see if it is possible to use a non-optional variable instead. The only other place you may use it is if your program truly could not recover from an optional being nil. In those circumstances, you should at least consider presenting an error to the user, which is always better than simply having your program crash.

An example of a scenario where it may be used effectively is with lazily calculated values. A lazily calculated value is the one that is not created until the first time it is accessed. To illustrate this, let's consider a hypothetical class that represents a file system directory. It will have a property listing its contents that is lazily calculated. The code will look similar to the following code:

Here, we have defined a superclass called FileSystemItem that both File and Directory inherit from. The content of a directory is a list of FileSystemItem. We define contents as a calculated variable and store the real value within the realContents property. The calculated property checks if there is a value loaded for realContents; if there isn't, it loads the contents and puts them into the realContents property. Based on this logic, we know for 100% certainty that there will be a value within realContents by the time we get to the return statement, so it is perfectly safe to use forced unwrapping.

Forced unwrapping

The

shortest way to unwrap an optional is to use forced unwrapping. It is done using an exclamation mark (!) after the variable name when being used:

However, the reason it is considered unsafe is that your entire program will crash if you try to unwrap an optional that is currently nil:

The complete error you get is unexpectedly found nil while unwrapping an optional value. This is because the forced unwrapping is essentially your personal guarantee that the optional truly does hold a value. That is why it is called "forced".

Therefore, forced unwrapping should be used in limited circumstances. It should never be used just to shorten up the code. Instead, it should only be used when you can guarantee from the structure of the code that it cannot be nil, even though it is defined as an optional. Even in that case, you should see if it is possible to use a non-optional variable instead. The only other place you may use it is if your program truly could not recover from an optional being nil. In those circumstances, you should at least consider presenting an error to the user, which is always better than simply having your program crash.

An example of a scenario where it may be used effectively is with lazily calculated values. A lazily calculated value is the one that is not created until the first time it is accessed. To illustrate this, let's consider a hypothetical class that represents a file system directory. It will have a property listing its contents that is lazily calculated. The code will look similar to the following code:

Here, we have defined a superclass called FileSystemItem that both File and Directory inherit from. The content of a directory is a list of FileSystemItem. We define contents as a calculated variable and store the real value within the realContents property. The calculated property checks if there is a value loaded for realContents; if there isn't, it loads the contents and puts them into the realContents property. Based on this logic, we know for 100% certainty that there will be a value within realContents by the time we get to the return statement, so it is perfectly safe to use forced unwrapping.

Nil coalescing

In addition

A common scenario in Swift is to have an optional that you must calculate something from. If the optional has a value, you will want to store the result of the calculation on it, but if it is nil, the result should just be set to nil:

This is pretty verbose. To shorten this up in an unsafe way, we could use forced unwrapping:

However, optional chaining will allow us to do this safely. Essentially, it allows optional operations on an optional. When the operation is called, if the optional is nil, it immediately returns nil; otherwise, it returns the result of performing the operation on the value within the optional:

So in this call, invitee is an optional. Instead of unwrapping it, we use optional chaining by placing a question mark (?) after it, followed by the optional operation. In this case, we are asking for the uppercaseInvitee property on it. If invitee is nil, uppercaseInvitee is immediately set to nil without even trying to access uppercaseString. If it actually does contain a value, uppercaseInvitee gets set to the uppercaseString property of the contained value. Note that all optional chains return an optional result.

You can chain as many calls as you want, both optional and non-optional, together in this way:

This code checks if the first element of the invitees-list starts with the letter A, even if it is a lowercase A. First, it uses an optional chain in case invitees is nil. Then the call to first uses an additional optional chain because that method returns an optional String. We then call uppercaseString, which does not return an optional, allowing us to access hasPrefix on the result without having to use another optional chain. If at any point any of the optionals are nil, the result will be nil. This can happen for two different reasons:

If the chain makes it all the way to uppercaseString, there is no longer a failure path and it will definitely return an actual value. You will notice that there are exactly two question marks being used in this chain and there are two possible failure reasons.

At first, it can be hard to understand when you should and should not use a question mark to create a chain of calls; the rule is to always use a question mark if the previous element in the chain returns an optional. However, so you are prepared, let's take a look at what happens if you use an optional chain improperly:

In this case, we try to call a method directly on an optional without a chain, so we get an error that says Value of optional type '[String]?' not unwrapped; did you mean to use '!' or '?'?. Not only does it tell us that the value is not unwrapped, it even suggests two common ways of dealing with the problem: forced unwrapping or optional chaining.

We also have the case where we try to use an optional chain inappropriately:

Here, we get an error that says Cannot use optional chaining on non-optional value of type '[String]'. It is great to have a good sense of the errors you might see when you make mistakes; so that you can correct them quickly because we all make silly mistakes from time-to-time.

Another great feature of optional chaining is that it can be used for method calls on an optional that does not actually return a value:

In this case, we only want to call removeAll if there is truly a value within the optional array. So with this code, if there is a value, all the elements are removed from it; otherwise, it remains nil.

In the end, option chaining is a great choice for writing a concise code that still remains expressive and understandable.

There is a second type of optional called an implicitly unwrapped optional. There are really two ways to look at what an implicitly unwrapped optional is; one way is to say that it is a normal variable that can also be nil; the other way is to say that it is an optional that you don't have to unwrap to use. The important thing to understand about them is that, similar to optionals, they can be nil, but you do not have to unwrap them like a normal variable.

You can define an implicitly unwrapped optional with an exclamation mark (!) instead of a question mark (?) after the type name:

Similar to regular optionals, implicitly unwrapped optionals do not need to be given an initial value because they are nil by default.

At first it may sound like it is the best of both worlds, but in reality it is more like the worst of both worlds. Even though an implicitly unwrapped optional does not have to be unwrapped, it will crash your entire program if it is nil when used:

A great way to think about them is that every time it is used, it is implicitly doing a forced unwrapping. The exclamation mark is placed in its type declaration, instead of each time it is used. This can be problematic because it appears the same as any other variable except for how it is declared. That means it is very unsafe to use, unlike a normal optional.

So if the implicitly unwrapped optionals are the worst of both worlds and are so unsafe, why do they even exist? The reality is that in rare circumstances, they are necessary. They are used in circumstances where a variable is not truly optional, but you also cannot give an initial value to it. This is almost always the case for custom types that have a member variable that is non-optional but cannot be set during initialization.

A rare example of this is with a view in iOS. UIKit, as we discussed before, is the framework Apple provides for iOS development. In it, Apple has a class called UIView that is used to display content on the screen. Apple also provides a tool in Xcode called Interface Builder that lets you design these views in a visual editor instead of in code. Many views designed in this way will need references to other views that can be accessed later, programmatically. When one of these views is loaded, it is initialized without anything connected and then all the connections are made. Once all of the connections are made, a function called awakeFromNib is called on the view. This means that these connections are not available to be used during initialization but are available once awakeFromNib is called. This order of operations also ensures that awakeFromNib is always called before anything actually uses the view. This is a circumstance where it is necessary to use an implicitly unwrapped optional. A member variable may not be able to be defined until after the view is initialized, when it is completely loaded:

Notice that we have actually declared two implicitly unwrapped optionals. The first is a connection to a button. We know that this is a connection because it is preceded by @IBOutlet. This is declared as an implicitly unwrapped optional because connections are not set up until after initialization, but they are still guaranteed to be set up before any other methods are called on the view.

This then leads us to unwrapping our second variable, buttonOriginalWidth, implicitly because we need to wait until the connection is made before we can determine the width of the button. After awakeFromNib is called, it is safe to treat both button and buttonOriginalWidth as non-optional.

You may have noticed that we had to dive pretty deep into app development to find a valid use case for implicitly unwrapped optionals and this is arguably only because UIKit is implemented in Objective-C, as we will learn more about in Chapter 10, Harnessing the Past – Understanding and Translating Objective-C. This is another testament to the fact that they should be used sparingly.

We have already seen a couple of the compiler errors we will commonly see because of optionals. If we try to call a method on an optional that we intended to call on the wrapped value, we will get an error. If we try to unwrap a value that is not actually optional, we will also get an error. We also need to be prepared for the runtime errors that optionals can cause.

As we have discussed, optionals cause runtime errors that are also referred to as crashes, if you try to forcefully unwrap one that is nil. This can happen with both explicit and implicitly forced unwrapping. If you have followed my advice so far in this chapter, this should be a rare occurrence. However, we all end up working with a third party code and maybe they were lazy or maybe they use forced unwrapping to enforce their expectations about how their code should be used.

Also, we all suffer from being lazy from time to time. It can be exhausting or discouraging to worry about all the edge cases when you are excited about programming the core functionality of your app. We may use forced unwrapping temporarily while we worry about that main functionality and plan to come back to handle it later. After all, during development it is better to have a forced unwrapping crash the development version of your app than it is for it to fail silently if you have not yet handled that edge case. We may even decide that an edge case is not worth the development effort of handling because everything about developing an app is a trade off. Either way, we need to recognize a crash from forced unwrapping quickly so we don't waste extra time trying to figure out what went wrong.

When an app tries to unwrap a nil value, if you are currently debugging the app, Xcode will show you the line that is trying to do the unwrapping. The line will report that there was an EXC_BAD_INSTRUCTION error and you will also get a message in the console saying fatal error: unexpectedly found nil while unwrapping an Optional value:

Debugging optionals

You will also sometimes have to look at what code is currently calling the code that failed. To do that, you can use the call stack in Xcode. The call stack is the full path of all function calls that got to this location. So, if you have function1 call function2, which then calls function3, function3 will be at the top and function1 will be at the bottom. Once the execution exits function3, it will be removed from the stack so you will just have function2 on top of function1.

When your program crashes, Xcode will automatically display the call stack, but you can also manually show it by navigating to View | Navigators | Show Debug Navigator. It will look similar to the following screenshot:

Debugging optionals

Here, you can click around different levels of code to see the state of things. This will become even more important if the program is crashing within one of Apple's framework, where you do not have access to the code. In that case, you will want to move up the call stack to the point where your code called into the framework. You may also be able to look at the names of the functions to help you figure out what may have gone wrong.

Anywhere on the call stack, you can look at the state of the variables in the debugger, as shown:

Debugging optionals

If you do not see this variable's view, you can display it by clicking on the button in the bottom-right corner of the screen, second from the right that will be grayed out. Here, you can see that invitee is indeed nil, which is what caused the crash.

As powerful as the debugger is, if you find that it isn't helping you find the problem, you can always put print statements in important parts of the code. It is always safe to print out an optional, as long as you don't forcefully unwrap it as shown in the preceding example. As we have seen before, when an optional is printed, it will print nil if it doesn't have a value, or it will print Optional(<value>) if it has a value.

Debugging is an extremely important part of becoming a productive developer because we all make mistakes and create bugs. Being a great developer means that you can identify problems quickly and understand how to fix them soon after that. This will largely come from practice, but it will also come from having a firm grasp of what is really happening with your code versus simply adapting some code you find online to fit your needs through trial and error.

At this point, you should have a pretty strong grasp of what an optional is and how to use and debug it, but it will be valuable to look a little deeper at optionals to see how they actually work.

In reality, the question mark syntax for optionals is just special shorthand. Writing String? is equivalent to writing Optional<String>. Writing String! is equivalent to writing ImplicitlyUnwrappedOptional<String>. The Swift compiler has the shorthand versions because they are so commonly used. This allows the code to be more concise and readable.

If you declare an optional using the long form, you can see Swift's implementation by holding Command and clicking on the word Optional. Here, you can see that Optional is implemented as an enumeration. Simplifying the code a little, we have:

So we can see that an optional really has two cases: None and Some. None stands for the nil case, while the Some case has an associated value, which is the value wrapped inside the optional. Unwrapping is the process of retrieving the associated value out of the Some case.

The one part of this that you have not seen yet is the angled bracket syntax (<T>). This is called a generic and it essentially allows the enumeration to have an associated value of any type. We will cover generics in-depth in Chapter 6, Make Swift Work For You – Protocols and Generics.

Realizing that optionals are simply enumerations will help you understand how to use them. It also gives you some insight into how concepts are built on top of other concepts. Optionals seem really complex until you realize that they are just a two case enumeration. Once you understand enumerations, you can pretty easily understand optionals as well.