What's New in Swift 2
At WWDC15, Apple announced Swift 2. In this article, I’ll go over some of the features you’re most likely to use. Swift 2 works with Xcode 7, which is also now available.
Strings
Getting the total string count or trying to determine if a character exists in another string has changed in Swift 2. You can now access the character's property to get either.
We’ll work with the following variable:
var myString = "Hello World"
Get the total character count:
myString.characters.count
Find a character within another string:
myString.characters.contains"H")
contains()
returns a boolean. In this case, it will return true. If you want to find a string within a string, use the following:
myString.containsString("He")
Loops
The do...while
loop has been replaced with the repeat...while
loop. This might seem like a subtle difference and actually it is. Apple wants to make the loop’s intention clearer. Depending on what is between the repeat
and while
keywords, it might not be so clear if that block of code is very large. With the repeat keyword, you know there is a loop
going on, no matter how far down the while
keyword might be.
Below is an example of the repeat...while
loop. Functionality, it doesn’t do anything different from the do...while
loop.
var i = 0
repeat {
print("an iteration")
i++
} while i < 5
Printing Output
In Swift 1.2, we could output comments into the debugger using println()
. In Swift 2, that has now been replaced with just print()
.
#available
Now you can check which version of iOS you’re running on and execute code for that version or later. This includes WatchOS. It’s all done with the #available
keyword. Here’s an example that checks if we’re running iOS9 or later:
if #available(iOS 9.0, *) {
//do something specific to iOS9
}
The “*” part is required and checks for OS’s such as WatchOS. The code within the conditional will execute only if we are running on iOS9 or later.
If you try to use a feature that requires a specific version of iOS, you might get an error in Xcode. Clicking the error will actually reveal a fix. By choosing the fix, Xcode will surround the offending code with an #available
conditional, inserting code for the correct iOS version.
Guard
In Swift 1.2, we got used to the if...let
style of syntax when checking if an optional variable had a value. Swift 2 introduces the guard statement, which makes things more concise.
Swift 1.2
var networkData = String?()
networkData = "test"
if let verifiedNetworkData = networkData {
print("item was not nil. value=" + verifiedNetworkData)
}
else {
print("networkData was nil")
}
Since networkData
is assigned a value, the constant verifiedNetworkData
will get the same value. If we comment out networkData
, verifiedNetworkData
never existed and the second print statement executes - ”networkData was nil”.
Swift 2
func myFunc(nd:String?){
guard let verifiedNetworkData2 = nd else {
print("not valid")
return
}
print("valid")
}
myFunc(networkData)
With the guard statement, we express better intent of what the code is doing. Guard will check for the positive case. Or the case we’re looking for. Any other case (the case we don’t want) goes into the else.
Error Handling
Swift 2 provides for great error handling compared to what was there before. We can now declare error types and use them in try/catch code blocks. In the example below, we create an ErrorType enum:
enum invalidCharacterError: ErrorType {
case unknown
case invalid
}
Next, we have a function that makes use of the error type. Notice the use of guard
. This creates a shorthand syntax that works with our error. If the condition does not pass, we throw the error.
In this case, we want to make sure the invalid characters “@@“ are not passed into our function. If they are, we throw the error. Otherwise, we return true.
func checkInvalidCharacters(inputString: String) throws -> Bool
{
guard inputString != "@@" else {throw invalidCharacterError.invalid}
return true
}
The following code executes the above method. Since invalid characters are being used, an error is thrown. The first catch will handle the error. It is necessary to provide a default catch.
do {
let checkPassed = try checkInvalidCharacters("@@")
}
catch invalidCharacterError.invalid {
print("invalid character error")
}
catch {
print("unknown error occurred")
}
The do
keyword starts the error test. Within the do code block, we can execute any code that we are testing an error against. The try keyword is also necessary so we know specifically which line of code we are testing.
Notice also that the do keyword is used for our do/try/catch construct. Recall that the do/while loop is no longer used. do actually got moved to the error handling section. One more reason why we see a repeat/while loop and not a do/while loop.
Summary
Try the examples above in the Playground to get familiar with them. Since all examples were created in the Playground, you don’t have to worry about app scaffolding getting in the way.
Swift 2 introduces many new features that can enhance your code. The Swift 2 migrator also works well for bringing over earlier versions of Swift code. While we know Swift syntax will change, getting to know its newest features will provide you with a deeper knowledge and appreciation for the language.