Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use optional binding in Swift 2

I'm new to learning Swift so I decided I might as well learn Swift 2 instead. Everything has made sense to me so far except for the following code snippet. Hopefully someone can shed some light on this for me.

//: Playground - noun: a place where people can play
import UIKit

//Works
let possibleNumber="2"
if let actualNumber = Int(possibleNumber) {
    print("\'\(possibleNumber)\' has an integer value of \(actualNumber)")
}
else {
    print("could not be converted to integer")
}

//Doesn't Work and I'm not sure why
let testTextField = UITextField()
testTextField.text = "2"
let numberString = testTextField.text  //I know this is redundant

if let num = Int(numberString) {
    print("The number is: \(num)")
}
else {
    print("Could not be converted to integer")
}

The top section of the code is straight from Apple's Swift 2 ebook and it makes sense to me how it uses optional binding to convert the string to an int. The second piece of code is basically the same except that the string comes from the text property of a UITextField. The bottom part of the code gives the following error:

Playground execution failed: /var/folders/nl/5dr8btl543j51jkqypj4252mpcnq11/T/./lldb/843/playground21.swift:18:18: error: value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'? if let num = Int(numberString) {

I fixed the problem by using this line:

if let num = Int(numberString!) {

I just want to know why the second example needs the ! and the first doesn't. I'm sure the problem has to do with the fact that I'm getting the string from a textfield. Thanks!

like image 786
jobber80 Avatar asked Jul 04 '15 17:07

jobber80


People also ask

How do you use optional binding?

An if statement is the most common way to unwrap optionals through optional binding. We can do this by using the let keyword immediately after the if keyword, and following that with the name of the constant to which we want to assign the wrapped value extracted from the optional.

What is optional binding in Swift?

Optional Binding is used to safely unwrap the optional value. Step one: We assign our optional value to temporary constant & variable. Step Two: If the optional variable contains a value it will be assigned to our temporary variable.

How does Swift handle optional value?

Optional Handling. In order to use value of an optional, it needs to be unwrapped. Better way to use optional value is by conditional unwrapping rather than force unwrapping using ! operator.

What is the use of optional in Swift?

Optionals are in the core of Swift and exist since the first version of Swift. An optional value allows us to write clean code with at the same time taking care of possible nil values. If you're new to Swift you might need to get used to the syntax of adding a question mark to properties.


1 Answers

The difference is that in the first case possibleNumber is not an optional variable. It is definitely a string. It cannot be nil.

In the second case textField.text returns an optional string and so numberString is an optional variable. It could be nil.

Now... The conversion Int("") returns an optional int. if the string is "abc" then it cannot return a number so returns nil. This is what you are unwrapping with the if let... statement.

However, in the second case your string is also optional and the Int() will not accept an optional. So you are force unwrapping it. This is dangerous as it could crash the app if the string is nil.

What you could do instead is this...

if let numberString = textFeidl.text,
    number = Int(numberString) {
    // use the number
}

This will unwrap the text first and if it's available then use it to. Get the number. If that is not nil then you enter the block.

In Swift 2 you could use the guard let function here also.

Just seen that you are using Swift 2.

You can do it this way also...

func getNumber() -> Int {
    guard let numberString = textField.text,
          number = Int(numberString)
          else {
          return 0
    }

    return number
}
like image 183
Fogmeister Avatar answered Sep 19 '22 01:09

Fogmeister