With wwdc2015 came many apis for us iOS developers to explore and to use. Added value for that have iOS apps. In this post, I’ll focus more on what’s new in Swift 2.0 and some of the new features in Xcode. I will also mention some of my favorite tips and tricks in Xcode if I have the time.
guard
I love this statement so far. you would want to use the guard statement instead of checking for negativity with an if-statement. let’s say that we have an optional value in our class and we want to make sure that it contains a value and that its length is more than 0. with traditional if statements we would do something like this:
note: sorry about wordpress’ horrible code formatting or lack of it, must I say!
var firstName: String?
override func viewDidLoad() { super.viewDidLoad()
if let name = firstName where name.characters.count > 0 { //handle success } else { //handle error }
}
well if you are like me, you might have a few of these if statements and then your code will become an if-statement spaghetti. what you want really is to exit your function quickly if a set of requirements is not met. that’s what the guard statement takes care of. here is the same code with guard:
var firstName: String?
override func viewDidLoad() { super.viewDidLoad()
guard let name = firstName where name.characters.count > 0 else { return }
//now you can use the name variable as an unwrapped String print(name)
}
you can indeed unwrap multiple variables in the same line and have various conditions on them like so:
guard let name = firstName, let lastName = lastName where name.characters.count > 0 && lastName.characters.count > 0 && firstName != lastName else { return }
//now you can use the name variable as an unwrapped String print(name)
Error handling
strange that swift added this traditional type of error handling with try and catch but let’s have a look at it anyways. Any method now can throw an error. errors are specified with the ErrorType protocol. any enumeration that comes from ErrorType can have its members thrown using the throw keyword. methods can also be marked to throw an exception. you can catch the exceptions using the do, try, catch syntax.
let’s see how we can define an error first
enum Errors : ErrorType{ case EmptyString }
then we can define a method that can under specific circumstances throw this error:
func reverse() throws -> String { guard self.characters.count > 0 else { throw Errors.EmptyString } return String(self.characters.reverse()) }
note: this is an extension on the String class
and then we can start using this method:
do { let reversedName = try "".reverse() print(reversedName) } catch let err { print(err) }
remember that you can chain your catch statements to catch various different types of exceptions:
do { let reversedName = try "".reverse() print(reversedName) } catch let err as NSException where err.name.characters.count > 0 { //catch an exception with a name } catch let err { print(err) }
print()
Yes, println() is now renamed to print() and this method has a few overloads one of which takes a parameter named appendNewline that is boolean. so that you can do things like this:
for c in "Vandad".characters { print(c, appendNewline: false) }
even though this example is quite useless and verbose for what it wants to achieve, i think it proves the point.
Protocol extensions
protocols have always been like interfaces in Java: no implementation allowed. Well, that’s changed now. and here is an example. let’s say that we have a “Paintable” protocol like so:
protocol Paintable { func move() var paintColor: UIColor {get set} }
and a struct that conforms to this protocol:
struct Car : Paintable {
var paintColor = UIColor.redColor()
func move() { //no code for now }
}
and now we want to make all Paintable subscribers able to have a convenient method that changes their paint color to white:
extension Paintable { mutating func paintWhite() { paintColor = UIColor.whiteColor() } }
API availability checking
we all know about respondsToSelector: and hacks like that which we have been used to in order to check the availability of specific APIs on the host device before calling them. now Swift has added an internal syntax to check for this type of availability. For instance, the getBytes: method on NSData is deprecated in iOS 8.1 and is replaced with getBytes:length: method:
let s = "Vandad" guard let d = s.dataUsingEncoding(NSUTF8StringEncoding) else { return }
var buffer = [UInt8](count: d.length, repeatedValue: 0)
if #available(iOS 8.1, *) { d.getBytes(&buffer, length: d.length) guard let string = String(bytes: buffer, encoding: NSUTF8StringEncoding) else { return } print(string) } else { d.getBytes(&buffer) }
That’s it for now. Thanks for reading.