Swift Introduction/SwiftAdvanced

= 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. 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  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. is short syntax for the first passed in argument,  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  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  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. 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. is called before a value is stored,  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. 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. 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. 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. 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  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  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   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  error is thrown. If a certain number of cups was served, the  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  error is caught, the machine asks for maintenance and the counter is set back to 0.

Converting Errors to Optional Values
With the  keyword, an error is converted to an optional value. The value of an expression is  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  testing framework and the Calculator. In the test functions,   and   an instance of the Calculator class is used to call the methods add, subtract and multiply to compare the result to an expected value.