Swift 2
At the 2014 WWDC conference Apple announced Swift as a new language to write iOS app. In February 2015 they released Swift 1.2, which fixed a lot of issues (especially with the compiler) and added new language features.
In June 2015 Apple announced at WWDC Swift 2, which will be made open source later this year. In this post I will cover the new features in Swift 2.
New features in Swift 2
Println
If you want to write debug messages to the console, prior to Swift 2 you have probably used println("the message")
a lot. In Swift 2, print
now automatically prints a message on a new line. Hey … it’s all about the small things.
Enums
Enums are one of the 3 data structures in Swift and are a great way to hold a small set of data. For example
enum OSXVersion {
case Lion
case MountainLion
case Mavericks
case Yosemite
case ElCapitan
}
SwiftBecause enums are in fact a data type, you can set a variable to be of type OSXVersion
.
var myOS:OSXVersion = .Lion
SwiftBut if you were to print out the value of myOS
in Swift 1.2, you would end up with (EnumValue)
.
println(myOS) // Prints `(Enum Value)`
SwiftRepeat
The do-while
loop has been renamed to repeat-while
in Swift 2.
var i = 0
do {
println(i)
i++
} while( i < 10 )
In Swift 2 it looks like this
var i = 0
repeat {
print(i)
i++
} while( i < 10 )
SwiftOption sets
Option sets are a great update for NS_OPTIONS and simplify the usage of bitflags. They are used to easily pass multiple options within one variable by using bitewise operations, but with option sets you don’t really need to worry about setting bits.
To create an option set, all you have to do is create a struct
which implements the OptionSetType
protocol. The only requirement of this protocol is that your struct has a rawValue
property.
struct FontOptions:OptionSetType {
var rawValue:Int
}
SwiftNow you can just add the different options you want to provide as static constants. Just make sure the rawValue of every option is a power of 2.
struct FontOptions:OptionSetType {
var rawValue:Int
static let StrikeThrough = FontOptions(rawValue: 1)
static let Bold = FontOptions(rawValue: 2)
static let Underline = FontOptions(rawValue: 4)
}
SwiftTo use this OptionSetType
, you just have to comma-seperate them in an array.
var style:FontOptions = []
style = [.StrikeThrough]
style = [.StrikeThrough, .Bold]
SwiftAnd if you want to check if a certain option was set, you can use the contains
function.
if style.contains(.Bold) {
// Set the style to bold
}
SwiftGuard
Guard is a new statement in Swift 2 which checks a condition and bails out if the condition is not met. So what is exactly the difference between guard
and an if
statement?
Assume the following Swift 1.2 code where we have a createPerson
function which can return a Person or a String (an error message for example). As you can see we need to unwrap the dictionary and check for the values, if both values are correct we can create the Person object, otherwise we return an error message.
enum Either<A,B> {
case Person(A)
case Error(B)
}
struct Person {
var name:String
var age:Int
}
func createPerson( dictionary:AnyObject ) -> Either<Person, String> {
if let name = dictionary["name"] as? String, let age = dictionary["age"] as? Int {
return .Person(Person(name: name, age: age))
}
return .Error( "Could not create person" )
}
SwiftWith the guard
statement this code would look like this.
func createPerson( dictionary:AnyObject ) -> Either<Person, String> {
guard let name = dictionary["name"] as? String,
let age = dictionary["age"] as? Int else {
return .Error( "Could not create person" )
}
return .Person(Person(name: name, age: age))
}
SwiftDoesn’t this look a lot nicer? We’re first checking if everything is OK, if not we do an early exit out of the function scope. Otherwise we return a new Person object. The nice thing with guard is that the unwrapped values name
and age
of the guard statement are also available in the fall-through.
Availability
I’m really excited about this new feature in Swift 2. Apple finally made it easy to add SDK dependant code.
A common idiom we used was to use respondsToSelector
with an if-statement
.
if loginButton.respondsToSelector("doSomethingWithNewSDK") {
// Do something
}
SwiftThis is highly error prone, as we can make a typo in the selector its name.
In Swift 2 you can use the #available()
directive.
if #available(iOS 9, *) {
// Do something
}
SwiftError handling
Swift 2 has some new ways on how to handle errors which removes some of the typical NSError boilerplate code.
Let’s say you want to ask a webservice for some data. Your code would probably look something like this.
func getNewsFromAPI() {
service.getNews()
// Do something after results are received
}
SwiftThe problem is that service.getNews
could fail, as there might not be an internet connection. You could solve this by working with NSError, but then our code would suddenly look like this.
func getNewsFromAPI( inout error:NSError?) -> Bool {
if( service.getNewsWithError(&error) ) {
return false
}
// Do something after results are received
return true
}
SwiftThis works … but it adds a lot of boilerplate code.
In Swift 2, we can now use the try
keyword.
func getNewsFromAPI() {
try service.getNews()
// Do something after results are received
}
SwiftNow we’ve indicated that the getNews()
method can fail. But how do we handle the error?
That’s pretty easy, we just have to indicate that the function can throw an exception.
func getNewsFromAPI() throws {
try service.getNews()
// Do something after results are received
}
SwiftIf you want to handle the error you just wrap it inside a do-catch
statement.
func getNewsFromAPI() throws {
do {
try service.getNews()
// Do something after results are received
} catch {
// Handle error
}
}
SwiftIf the service.getNews
method throws a specific error, you can pattern match it in the catch.
func getNewsFromAPI( ) throws {
do {
try service.getNews()
// Do something after results are received
}catch NewsError.NoInternetConnection{
// Handle specific error
}
catch {
// Handle error
}
}
SwiftDefining your own error types
Apple made it really easy now to create your own error types. You just have to implement the ErrorType
protocol on your class.
The easiest way is to use an enum
to hold the data for related errors. This is because enums
allow to hold extra data in the form of a payload (via associated values), and the compiler handles protocol conformance detail automatically.
So for example, say you created a class which connects to an API, you could create an APIErrors
enum, which groups the related errors that could happen when connecting to an API.
enum APIError : ErrorType {
case NoInternetConnection
case ServerDidNotRespond
case RequestTimeOut
}
SwiftNow you can just throw the error like this
if( noInternet ){
throw APIError.NoInternetConnection
}
SwiftWrapping up
As you see there are a lot of nice new features in Swift 2. I hope this give you a bit more insight in what is coming up.
To learn more, check out the following sites:
2 Responses
Is er al een officiële release date voor Swift 2?
Wellicht op het iPhone event op 9 september zal iOS ‘s avonds beschikbaar zijn of enkele dagen later. Vorig jaar was het 2 dagen voor dat de iPhone 6 gereleased werd.