Validating Strings for Numbers

Swift is gaining popularity with Developers and as companies are considering Swift for their projects. Over a period since the publication of my Swift book (at Swift v1.2) there are many that keep up to date with the new features in Swift and there are those that are now considering the move to Swift or have to since it is forced upon them. After looking at some of the articles on using Swift, I take for granted that most developers are using advance features with Swift. Over the next few articles are some basic mistakes or issues that many beginners make.

The problem

Let’s say you want to know if the value in a UITextField is a number or not. The easiest way is to check if the .text can be converted into a number or not. With Objective-C you could simply use the intValue or doubleValue to get a numeric value from NSString . However Strings in Swift do not have this functionality. It is commonly seen how many developers use code like

let num = NSString(string: theText).intValue

or

let num = (theText as NSString).intValue

Converting text to Int

The simplest way in Swift is to try and cast the text as an Int . If a string can be cast as Int, it returns a number (Int) and if the string is not a number, then it returns a nil. We can use this to simply return a Bool like

func isNumber(theString: String) -> Bool {
    return (theString != nil)
}

This works for us as we can get a true/false returned to us depending on if the string is a number or not. The only problem is that we can determine if the text contains a number or not, however to get the value, we need to cast it again, not very useful. However what if we modified our function a little and instead of returning a Bool , we can return an Int value. If the value is not a number, we can return a zero.

func getNumber(theText: String) -> Int {
    if let num = Int(theText) {
        return num
    } else {
        return 0
    }
}

This is all fine, but when we are trying to get the values from UITextField.text , the string is an optional. So the first issue that comes up is that we have to unwrap the optional as casting with Int takes a String , not a String? We can fix that like so

func getNumber(theText: String?) -> Int {
    if let theText = theText {
        if let num = Int(theText) {
            return num
        }
        return 0
    }
    return 0
}

This works fine. If you wanted to check for zero as a number and not use it as default, then you can return a number other than 0. Your options are to return a -1 or you can even use NSNotFound as a return value (to keep it pure swift, you can use something like Int.max )

Making it convenient with extensions

Working with Swift is so much easier and fun for a lot of reasons and one of them is the use of extensions. So instead of creating this function which is called everytime, you could simply have an extension for strings that returns an Int value.

extension String {
    var toInt: Int {
        if let num = Int(self) {
            return num
        }
        return Int.max
    }
}

With this we can simply use something like

let theText1 = "1234"
let theText2 = "12&34"

print(theText1.toInt)
print(theText2.toInt)

this works fine, but if the strings were declared as optional, then we would see a rather interesting problem, the value required needs to be unwrapped, and you cannot use an optional. The easiest way is to simply use

let theText3: String? = "1234"
let theText4: String? = "12&34"

print(theText3?.toInt)
print(theText4?.toInt)

Applying it to UITextFields

You can now simply use this with values from UITextFields as simply as

let num = textField.text?.toInt

In closing

Now that you have seen getting a value from a textField, if you want to try something further, here’s a challenge. Return if the textField has a % sign at the end of the .text or not, and another to return the value contained (i.e. the number after removing the % sign). If that is too easy, you can also try to get the % as provided of a number (constant or taken from another UITextField).

Views All Time
Views All Time
1039
Views Today
Views Today
1
Posted in Basics, Tip, Tutorial, Uncategorized and tagged , , , , , .