Swift 2 focused on improving the language itself, interacting with Objective-C, and improving the performance of compiled applications. New features of 
Swift 2 are presented in 6 different areas:
- fundamental constructs of the language, such as enum , scoping (scope), argument syntax, etc.
 - pattern matching
 - availability check
 - protocol extensions
 - error handling
 - interaction with objective-c
 
I will consider the new features of Swift 2, accompanying them with examples whose code is on 
Github .
1. Fundamental language constructions
No more println ()
Usually we used the 
println () function to print a message on the console. In the Swift 2 version, we will use only 
print () . Apple combined the 
println () and 
print () functions into one. The 
print () function, by default, prints your message with a newline character "\ n". If you want, you can output a line without a newline:
')

map , filter and company
The definition of these convenient functions and methods through the collections in Swift 1.2 was not completely consistent. In Swift 1.2, there was no default implementation of the 
map method for the 
CollectionType protocol, since the default implementation of the protocol was not possible and extensions were made only for classes. Partly for this reason, 
map was defined as a method in the 
Array class (which implements the 
CollectionType protocol), and not defined in the 
Set class (which also implements the 
CollectionType protocol). In addition to this, the global 
map function was disclaimed, which took an instance of 
CollectionType as the first parameter. This created complete confusion.
// Swift 1.2 let a: [Int] = [1,2,3] //    map   Array let b = a.map{ $0 + 1 } //      map  map([1,2,3]) { $0 + 1 } let set = Set([1,2,3]) //  ,    map   Set set.map{ $0 + 1 } //   map   Set map(set) { $0 + 1 } 
It turned out that, depending on the type of collection, either the global 
map function is used, or the 
map method of this collection. It looks inconsistent and poorly readable if a chain of transformations is used using the methods and functions of 
map , 
filter and 
reduce .
Now, in Swift 2, protocol extensions are allowed, therefore 
map , 
filter & co are implemented at the protocol level for 
CollectionType , as protocol extensions. Therefore, the same methods will operate on 
Array , 
Set, or any other collection implementing the 
CollectionType protocol.
 // Swift 2 let a: [Int] = [1,2,3] let b = a.map{ $0 + 1 } let set = Set([1,2,3]) let anotherSet = set.map{ $0 + 1 } let sum = (1...100) .filter { $0 % 2 != 0 } .map { $0 * 2 } .reduce(0) { $0 + $1 } print(sum) // prints out 5000 
We see in the example above that 
filter now works on 
Range . This did not work in the previous version, because, although 
Range confirmed the 
CollectionType protocol, the 
filter method was not implemented. Now everywhere we have a much more understandable syntax of these methods for any collection.
Enum enums
In Swift 2, 
enum has sufficient 
reflection information to enable their printing.

The 
print (an) clause will now print 
Dragon correctly, although in the previous version of Swift, the output was completely non-informative 
(Enum Value) .
Another improvement regarding 
enum is that Swift now allows you to represent the associated values of various types in 
enum . As an example, you can now legally present the 
Either type:

Now 
enum can be recursive, that is, we can build a tree using 
enum . Let's look at this example:

We must use the 
indirect keyword in front of 
case Node . And it allowed us to create a tree:

Here's what it looks like:

Now we can create a function that recursively traverses the entire tree and adds the numbers:

A result of 21 must be printed.
Diagnostics.
In addition to this, Swift 2 brought a huge number of improvements in diagnosing errors and assumptions to correct them, such as correctly defining a developer’s attempt to modify 
var using an immutable 
struct method, or when the 
var property never changes after initialization or when the result of a function call and etc.
One of the simplest changes makes the code more readable. As you know, Swift developers prefer to declare many things as constants, using 
let , rather than variables, using 
var . But what if you accidentally used the keyword 
var? Or did you think that you need to change it, but did not do it? Both Xcode 7 and Swift 2 will give you a warning that you don’t change this variable anywhere in your code - Xcode literally explores all uses of the variable and knows for sure whether you changed it or not.
Many options (Option Sets)
The set of options is a way of representing a set of Boolean values, and in Swift 1.x it looked like this:
 viewAnimationOptions = nil viewAnimationOptions = .Repeat | .CurveEaseIn | .TransitionCurlUp if viewAnimationOptions & .TransitionCurlUp != nil { ... 
This type of syntax was widely used in Cocoa, but in reality, it is only a “relic” of the C language. So, in Swift 2, it is removed and its own type is presented for many options, it is the 
OptionSetType protocol:

So now the set of options can be any type of 
Set or 
struct , confirming the 
OptionSetType protocol. This leads to a clearer syntax when using multiple options:

The syntax does not rely on “bit” operations, as in previous versions, and does not use 
nil to represent an empty set of options.
It should be noted that the many 
OptionSetType options now rely on another feature in Swift 2, called the “default” implementation implementations for protocol extensions, so simply confirming the 
OptionSetType protocol, you get a default implementation, for example, for the method 
contains , 
subtractInPlace , 
unionInPlace and other set operations. We will look at protocol extensions later.
Functions and methods
The Swift 1.x syntax for declaring functions and methods was inherited from two different conventions originating from C, where the function arguments have no labels, and Objective-C, which labels the methods arguments. So you had such declarations:
 func save(name: String, encrypt: Bool) { ... } class Widget { func save(name: String, encrypt: Bool) { ... } save("thing", false) widget.save("thing", encrypt: false) 
In Swift 2, the above code would look like this:

So the functions get the same convention as the methods:
- implies that the name of the first argument is contained in the function name;
 - subsequent arguments have labels.
 
However, these changes do not apply to functions imported from the C and Objective-C APIs.
Additionally, the parameter label declaring model has become more convenient since the 
#option option, which was used in Swift 1.x to denote a parameter with the same internal ( 
internal ) and external ( 
external ) name, has been removed.
Scoping Operators
The new 
do clause allows developers to explicitly define the explicit scope of variables and constants. This can be useful for re-using already declared names or for early release of some resources. The 
do clause looks like this:

In order to avoid ambiguity with the 
do ... while clause, which is presented in earlier versions of Swift 1.x, the latter was renamed to 
repeat ... while in Swift 2.
UNIT testing
The problem with unit-testing Swift 1.x code is that Swift 1.x made you mark the 
public word with all that you want unit-testing to see. As a result, there are 
public notes where they should not be. All this is due to the fact that 
Test Target is different from 
Application Target , and files from your application that are 
internal are not available for 
Test Target .
In Swift 2, substantial unit relief has been achieved. Xcode 7 automatically compiles Swift 2 code in a special "test" mode

to access all 
internal definitions as if they are defined as 
public . This is done using the 
@testable attribute when importing our module.

That's all it takes, and you don't need to mark anything with the word 
public .
Moreover, these changes do not affect the main release of your application, maintaining the correct behavior both in terms of performance and in terms of access control.
2. Control the order of calculations
Swift 2 introduced new concepts for managing the order of computation, and improved existing structures.
Offer guard
The 
guard clause, as well as the 
if clause, executes the code depending on the Boolean value of the conditional expression. You use the 
guard clause to, if the Boolean value is 
true , continue the code following the 
guard clause.
A 
guard clause is essentially the inverse of an 
if clause. For 
if, we write:
 if condition { // true  } else { // false  } 
For 
guard , 
true the branch rises to a higher level compared to the 
false branch:
 guard condition else {  
Notice that the 
false branch should end execution in a closed context (scope), returning a value or “throwing” (throw) an error. You guarantee that the code in the 
true branch will be executed only if the condition is met.
This makes 
guard a natural way to check non-fatal preconditions without using the “Smetri pyramid” formed by nested 
if statements and without inversion of conditions.
Let's see what a typical code path looks like when using the traditional 
if statement .

The 
jsonDict dictionary is input to the 
createPersonFromJSON function, and a valid instance of the 
Person structure is created at the output if the corresponding information is presented in the dictionary, otherwise 
nil is returned. The function is written as it would appear in Swift 1.2 - using the 
if let construct. There are a couple of “pain points” in this code. First, the “turning off” of the direction of correct calculations from the main code, that is, the “successful” (in terms of condition) direction of calculations turned out to be “nested” in the 
if let clause. Secondly, the 
createPersonFromJSON function 
does not always return an instance of 
Person when we need it. The 
Person structure contains 3 properties, one of which is 
Optional , but the function returns the correct instance of 
Person only if we get values from the dictionary that are different from 
nil for all 3 keys. Let's rewrite this function as follows: so that we can return an instance of 
Person if the address is missing, that is, if the 
address key returns 
nil .

We made a slight improvement in functionality. This version of the 
createPersonFromJSON2 function can now instantiate 
Person even if the address is 
nil . This reflects the 
Person structure better, but now we have a lot of 
if statements , as well as the need to expand the final values assigned to 
name and 
age . Let's see how this can be improved with the new 
guard clause.

In the case of 
guard clauses, as well as with the 
if let clause, we can check for the presence of values, “expand” them and assign them to constants. However, with the 
guard let construct, code execution continues after curly braces 
{} , if the conditional expression is evaluated as 
true . This means that we can instantiate 
Person within the normal scope of the function without using additional code branching to expand the values. If any of the 
name or 
age values is 
nil , then the code "jumps" to the 
else clause and an early return 
nil is performed.
Let's take a quick look at 
guard .
- If the condition of the guard clause is satisfied, execution of the code continues after the curly braces of the guard sentence are closed;
 - If this condition is not met, then the code in the else “branch” is executed; unlike if , guard always has an > else block;
 - The else clause must transfer control beyond the normal scope of the function using return , break , continue > or by calling another function or method.
 
.
Offer defer
The 
defer clause resembles 
finally in other programming languages, except that it is not tied to a 
try clause, and you can use it anywhere. You write 
defer {...} and somewhere in the code and this block will be executed when the calculation control leaves this code scope (enclosing scope), and it does not matter whether the code gets to the end or receives the return clause or “throws An error. The operator defer is perfectly combined with 
guard and error handling (discussed later).
 guard let file1 = Open(...) else { //   file1 return } defer { file1.close() } guard let file2 = Open(...) else { //   file2 return } defer { file2.close() } //  file1  file2 . . . . . . . //      ,    
Note that 
defer works for 
file1 both in the normal course of the computational process and in the case of an error with the file 
file2 . This removes numerous repetitions from the code and helps you not to forget to “clear” something in any branch of the calculations. When handling errors, there is the same problem and the 
defer clause is 
best suited for this purpose.
Repeat - while
Swift 2.0 introduced syntactic changes to the 
do-while clause that was used before. Instead of a 
do-while , we now get a 
repeat-while .

There are two reasons for such changes:
When you use the 
do - while loop, it is immediately unclear that this is a construct to be repeated. This is especially true if the block of code inside the 
do clauses is large, and the 
while condition is outside the screen. To mitigate this circumstance, the 
do keyword has been replaced by 
repeat , which makes it clear to the user that this is a duplicate block of code.
The keyword 
do has a new assignment in Swift 2 in the new error handling model, which we will explore later.
Pattern matching
Swift has always had the power of 
pattern matching , but only in the 
switch construction. The 
switch construct considered the value 
value and compared it with several possible patterns. One of the drawbacks of the 
switch clause is that we have to present all possible options for the 
value , that is, the 
switch statement must be exhaustive and this causes inconvenience of use. Therefore, Swift 2 ported 
pattern matching capabilities, which previously were only for 
switch / case , to other sentences that control the flow of computations. 
if case is one of them, and it allows you to rewrite the code with the 
switch more briefly. Other sentences are 
for case and 
while case .
Pattern matching if case
New in Swift 2 is support for 
pattern matching inside 
if (and 
guard ) clauses. Let's first define the simplest enumeration 
Number , and then show how to use it.

1. Check a specific option (case)
Use 
case : we want to check if the value matches a specific 
case . This works regardless of whether this 
case has an associated value or not, but the value is not restored (if it exists).

The pattern starts with 
case .IntegerValue , and the value that must match this pattern, the 
myNumber variable, comes after the 
= equality sign. This may seem illogical, but we see the same thing when the 
Optional is expanded by the 
a1 value in the 
if let a = a1 construction: the 
a1 value that is being checked comes after the equal sign.
Here is the equivalent version of Swift 1.2 using 
switch :

2. Getting the associated value
We use 
case : we want to check whether the value corresponds to a specific 
case , and also to extract the associated value (or values).

The “pattern” has now become 
case let .IntegerValue (theInt) . The value that must match the “sample” is the same as in the previous example.
Below is an example reflecting the same concept, but applied to 
guard . The predicate semantics for 
guard and 
if are identical, so 
pattern matching works just as well.

3. Selection using the where clause
An optional 
where clause may be added to any 
case in the 
guard clause to provide additional restrictions. Let's modify the 
getObjectInArray: atIndex: function from the previous example:

4. Matching range

5. Use the tuple tuple

6. Complex if predicates
The if sentence in Swift 2 was surprisingly capable. It can have multiple predicates separated by a comma. Predicates fall into one of three categories:
- The simplest logical tests (for example, foo == 10 || bar> baz ). There can be only one such predicate and it should be placed in the first place.
 - Expanding Optional (for example, let foo = maybeFoo where foo> 10 ). If another option's immediate predicate is immediately followed by the optional deployment predicate, then you can skip the let. It can be added with the where qualifier.
 - Pattern matching (for example, case let. Bar (something) = theValue ), is what we looked at above. It can be added with the where qualifier.
 
Predicates are evaluated in the order of their definition and after not completing a predicate, the rest are not evaluated.
Pattern matching for case
Pattern matching can be used in conjunction with the 
for -in loop. In this case, our intention is to go through the elements of the sequence, but only on those that correspond to a given “pattern”. Here is an example:

Note that just like the “patterns” in the 
switch clause, you can retrieve a set of associated values and use 
_ if you are not interested in this associated value. If necessary, you can also add additional constraints using the 
where clause.
Pattern matching while
Pattern matching can also be used with a 
while loop. In this case, we will repeat the body of the loop until a certain value in the predicate matches the “pattern”. Here is an example:

Note that the complex predicates described in section “6. Complex if ”predicates are also supported by a 
while loop , including the use of 
where .
Pattern for "unwrapping" numerous optional
In Swift 1.2, we had a nice compact syntax for “deploying” the 
Optionals set in one simple 
if let clause:
 var optional1: String? var optional2: String? if let optional1 = optional1, let optional2 = optional2 { print("Success") } else { print("Failure") } 
Great!
However, you still encounter a situation where you really need to manage various combinations of existing / missing 
Optional values. One such example is the form to fill in the 
username and 
password fields, and the user did not fill in one of them, and clicked the "Submit" button. In this case, you will want to show a special error in order to notify the user what exactly is missing. To do this, we can use the 
pattern makching in Swift 1.x!
 var username: String? var password: String? switch (username, password) { case let (.Some(username), .Some(password)): print("Success!") case let (.Some(username), .None): print("Password is missing") case let (.None, .Some(password)): print("Username is missing") case (.None, .None): print("Both username and password are missing") } 
It's a little awkward, but we enjoyed it right from the start.
In Swift 2, the syntax looks clearer:

At first glance, confused by the use of a question mark 
? to show that the value is present (especially if it is associated with the idea of 
Optionals , when the value may or may not exist), but it must be recognized that this example becomes very understandable in contrast to the awkward syntax 
.Some (username) .
Error processing
In order to understand the new features of Swift related to error handling, it will be useful to remember that there are 3 ways where a function can end abnormally (hereafter, for brevity, let's switch to jargon and say “fall”):
- Many functions can “fall” for one reasonably simple “inherent” reason, for example, when you are trying to convert a String to an Int; such cases are handled fairly well by returning Optional values;
 - At the other end of the spectrum there are logical programming errors that cause the array index to go out of bounds, inadmissible conditions, etc., it’s very difficult to deal with them and we don’t know how to manage them.
 - The third case is a detail error, a fixable error, for example, such as a file is not found, or a network error or the user has destroyed the operation (situational errors).
 
Handling errors of the third type related to the situation is what Swift 2 is trying to improve.If we consider a typical control scheme for such errors in Swift 1.x and Objective-C, then we find a scheme when the function takes the inout argument NSError? and returns Bool to represent the success or failure of the operation: //  error  ,    var error: NSError? // success  Bool: let success = someString.writeToURL(someURL, atomically: true, encoding: NSUTF8StringEncoding, error: &error) if !success { //     error: println("Error writing to URL: \(error!)") } 
This approach has many “dark” sides that make it less understandable, and what the method itself does, but more importantly, manual implementation of agreements regarding what is behind the returned Bool is required . If the method returns an object and received an error, then it returns nil ; if it is a boolean value, then false is returned, and so on. You need to know which method you are dealing with, what to check if the result is nil or false or something else when the method contains an NSError error object ? .
Very confusing syntax. All these difficulties are related to the fact that Objective-C could not return a set of values from a function or method, and if we need to notify the user about an error, such an ingrained way of handling it was suggested.Swift 2 got new error management. It uses the do-try-catch syntax that replaces NSError . Let's see how you can use this new syntax. I will consider a very simple example of handling such errors, which the optional returns perfectly cope with.values, and for which the new syntax is not intended. But the simplicity of this example will allow me to focus your attention on the mechanism of “throwing out” and “catching” errors, and not on the complexity of their semantic content. In the end I will give a real example of processing data coming from the network.Before an error can be thrown (throw) or caught (catch), it must be defined. You can define it in Swift 2 with the help of enum , which implements the ErrorType protocol :
In order for a function
to “throw out” (throw) an error, you need to announce the keyword throws in the function header :
Now this function can throw an error using the keyword throwand a link to a specific type of error:
If you try to call this function, the compiler will generate an error: “The function being called throws errors, and the reference to it is not marked with the try keyword and there is no error handling.”
Because the function declared that it is capable of throwing errors , and you have to “catch” potential mistakes. Let's try to use the keyword the try :
it was not enough, the compiler tells us that the required error handling, which is produced by using syntax do-try-catch :
Furthermore, in the block do-try-catch you have the opportunity to "catch" a few errors:
If the semantic part of errors does not interest you, then instead of using do-try-catch constructions , you can treat the values you are interested in as with Optional :
aTry and aTrySuccess are Optional , so don't forget to “deploy” them before use!Sometimes there is a method that can “fall” only in certain circumstances, and you know for sure that it will not “fall” in your mode of use. Then you can use try! .
If the function throws an error, it returns immediately. But sometimes you need to do some actions, such as freeing up resources or closing files, before the function returns. In this situation, the defer keyword already familiar to us works just fine . With the defer keyword, you can define a block of code that is always executed if the function returns, and it does not matter whether it returns normally or due to errors.We can define a defer block anywhere in our function. Moreover, it is possible to define more than one defer block. In this case, they will be performed in the reverse order. Let's look at an example:
Let us consider the real example presented in the Natasha Murashev article . Swift 2.0: Let's try? .
Consider the data that comes from an API (after deserialization):
This data needs to be converted to a Model for later use in an application:
The TodoItemParser parser deals with mixed data coming from an API, converts it into an understandable Model for later use in an application and “Throws” errors if it detects them:
Now we will perform the parsing of “good” data in the Model using the do-try-catch construction . We will perform the
parsing of “bad” data.
Instead of using the do-try-catch construct , you can treat the values that interest us as Optional with the try? :
In the first part, we considered only a part of the new features of Swift 2:- the fundamental constructs of the language, such as enum, scoping(scope), the syntax of the arguments, etc.- pattern matching ( pattern matching )- error handling ( error handling )In the second part, we will look at the rest:
- availability check ( availability Available checking )- extension ( the extensions ) protocol- interaction with Objective-CReferences used article:the New features in Swift 2What I Like in Swift 2A Beginner's guide to Swift 2the Error Handling in Swift 2.0 We doSwift 2.0 We do: for Let's try?Video Tutorial: What's New in Swift 2 Part 4: Pattern A Matchingthe Throw for What the Do not the Throwof The of the Best for What's in the New Swift