# Swift Advanced
## Closure Expressions

Closure expressions are unnamed, anonymous functions which can interact with values from their surrounding contextref name="error">Apple Inc. | 2017 | Closure Expressions | [online][accessed: 18.09.2017] | https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-ID94</ref>. They are short function-like constructs without a declaration or name. In this snippet, you can see the general syntax of a closure expression. It starts with opening curly brackets, a parameter list and a return value. They keyword in marks the beginning of the closure's body. After the return statement the expression is closed with a curly bracket.
If a closure is assigned to a function type, a shorthand syntax can be used because Swift can infer the data types from the context. In the shortest version, you only have to tell Swift what to do with the parameters. $0 is short syntax for the first passed in argument, $1 for the second, and so on.

### Trailing Closures

Closures can be passed to functions as arguments. A trailing closure can be used as the function's final argument. It's not written within the functions parentheses but right after them. In the snippet below, you can see how a closure is passed to Swift's map function. The map function can be called on an array, the closure is then executed on every item of the array. In this example, the map functions checks whether a year is a leapyear or not. All years are converted to a string and " is a leap year" is appended if the prerequisites are fulfilled.

## Properties

In Swift, there are two main types of properties. Stored properties are used to store values of variables and constants associated with a class or a structure. Computed properties are not used to store, but to compute values.

### Stored Properties

These properties are a part of an instance of a class or a structure. It can have a variable or a constant value.

### Computed Properties

These properties provide getters and setters to retrieve or set the value of a variable. In this example, the structure Circle has a computed property called diameter. It has a getter which returns the doubled value of the radius. The setter changes the value of the radius to the half of the new diameter. area is a read-only property, which means it does not have a setter.

### Property Observers

Property observers can be used to observe the state of a property and respond to changes. They are called whenever the value of a property is set. There are two types of observers. willSet is called before a value is stored, didSet is called after a value is stored.

## Concurrency with GCD

The dispatch framework includes a lot of language features, runtime libraries and system enhancements which improve the support for concurrent code execution on hardware with more than one core. The Grand Central Dispatch (GCD) submittes work to dispatch queues managed by the system.

### Concurrency vs. Parallelism

Parallelism is the term which describes the concept of executing two or more threads at the same time on multi-core processors. Devices with a single core can achieve concurrency with time-slicing. This is the process of switching between multiple threads through context switches. GCD manages a pool of threads. Codeblocks can be added to dispatch queue and the GCD decides what to execute.

### Queues

DispatchQueue represents the dispatch queues provided by GCD. The tasks, which you submit to the queues, are executed in a FIFO order, which means the first submitted task will always be the first one that gets started. There are two types of queues. Serial queues can only execute one task at any time. Concurrent queues can start multiple tasks at the same time. They are started in the order they were added and can finish in any order. The scheduling is managed by GCD, which means it controls when tasks are started. GCD provides a main queue, which is a serial queue and runs on the main thread. Tasks on the main queue are executed immediately. It is good practice to put all tasks, which change or update the UI, on the main queue. This makes sure the UI is always responsive. The four global queues are concurrent, shared by the entire system and divided in priorities - high, default, low and background. Queues can also be created by the user and can be serial or concurrent.
The priority is not specified directly, but by using Quality of Service (QoS) classes.
.user-interactive describes tasks which have to be done immediately, because otherwise the user experience would be bad. This QoS is used for UI updates and event handling.
.user-initiated represents tasks, which can be performed asynchronously and are started from the UI. These tasks are mapped into the high priority queue, because it is used when users are waiting for immediate results or tasks require user interaction to continue.
.utility represents long-running tasks. This class is used for I/O, networking and computations. Usually a progress indicator is used to make sure the user knows something is going on.
.background describes tasks, which the user usually is not aware of. It is used for tasks that do not need user interaction and are not time-sensitive, for example maintenance or prefetchting.

### Using queues in iOS

The following snipped can be found on Github and can be imported as Xcode project. As soon as the "Start" button is pressed, the function download(size: Int, label: UILabel, timeout: Int) is called twice with different input parameters. After they are put onto a global queue they asynchronously execute the simulation. After each iteration the amount is increased by 1. Next, the label which displays the progress of the download has to be updated. To do this, it is necessary to put the task back on the main queue, which makes sure that it is executed immediately. After a short timeout the next iteration starts.

## Error Handling

There are a lot of situations where errors can occure during the execution of your code. For example, when trying to read a file from your harddisk errors can occur due to missing permission or non-existing files. Swift provides couple of ways to deal with errors during code execution.
* Errors in a function can be propagated to the code calling the function
* do-catch statements
* optional values
* assert the error won't occur

### Propagating Errors with throwing Functions

The keyword throws is used in a function's declaration after the parameterlist. This function is then called a "throwing function". In the example below, an enum is used to define two types of possible errors. Whenever the makeCoffee function is called, the number of beans in the machine is decreased and a counter is increased. As soon as the beans are empty, an outOfBeans error is thrown. If a certain number of cups was served, the needsMaintenance error is thrown.

### Do-Catch

Do-Catch statements are used to execute different statements depending on what type of error is thrown. For example, here a needsMaintenance error is caught, the machine asks for maintenance and the counter is set back to 0.

### Converting Errors to Optional Values

With the try? keyword, an error is converted to an optional value. The value of an expression is nil whenever an error is thrown during the execution. In the snippet below, an error is thrown as soon as the digit that should be returned is no longer greater than zero.

## Accessing data from Sensors

Apple's mobile devices include a lot of sensors, including an Accelerometer, a Barometer, an Ambient light sensor and a Pedometer. iOS developers can access these sensors data in their projects with Swift.

### Pedometer

As an example, the snippet below shows how the Pedometer can be accessed and how data can be retrieved. This sensor is used for instance to count a persons steps. This project can be downloaded from GitHub.

## Unit Testing

In this section we will have a look at how simple unit tests can be implemented in Swift. For this purpose a simple class with three functions will be tested. The class contains variables for two integer values and three functions which can add, subtract or multiply those values.
Next, let's have a look at how this class can be tested. First of all we have to import the XCTest testing framework and the Calculator. In the test functions testAdd, testSub and testMul an instance of the Calculator class is used to call the methods add, subtract and multiply to compare the result to an expected value.

## References

* ↑ Kodeco | 2017 | Grand Central Dispatch Tutorial | [online][accessed: 18.09.2017] | https://www.kodeco.com/5370-grand-central-dispatch-tutorial-for-swift-4-part-1-2
* ↑ Apple Inc. | 2017 | Error Handling | [online][accessed: 18.09.2017] | https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html#//apple_ref/doc/uid/TP40014097-CH42-ID508
* ↑ Apple Inc. | 2017 | [online][accessed: 18.09.2017] | https://developer.apple.com/documentation/coremotion/cmpedometer
* ↑ Nolan, G. (2017), Agile Swift: Swift Programming Using Agile Tools and Tech- niques, Springer Science+Business Media New York, New York