Reputation: 802
I am trying to validate a form to make sure the user has entered an integer number and not a string. I can check if the number is an integer as follows:
var possibleNumber = timeRetrieved.text
convertedNumber = possibleNumber.toInt()
// convertedNumber is inferred to be of type "Int?", or "optional Int"
if convertedNumber != nil {
println("It's a number!")
totalTime = convertedNumber!
}
My problem is I want to make sure the user has not entered any text, doubles etc. I only want integer numbers. The following code does not work because it evaluates true if the variable is an integer. What code should I use to evaluate if variable is not an integer?
if convertedNumber != nil {
let alertController = UIAlertController(title: "Validation Error", message: "You must enter an integer number!", preferredStyle: .Alert)
let alertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Destructive, handler: {(alert : UIAlertAction!) in
alertController.dismissViewControllerAnimated(true, completion: nil)
})
alertController.addAction(alertAction)
presentViewController(alertController, animated: true, completion: nil)
Upvotes: 2
Views: 16949
Reputation: 7134
Int
initializerThis works in Swift 2.2 and above. It is based on Minhal Khan's answer which illustrates that Int
has an initializer with this signature: init?(_ text: String, radix: Int = default)
. Since radix
has a default value, it can be left out. *more info on this initializer is found here.
var totalTime: Int?
let possibleInt = timeRetrieved.text ?? ""
if let convertedNumber = Int(possibleInt) {
print("'\(possibleInt)' is an Int")
totalTime = convertedNumber
}
else {
print("'\(possibleInt)' is not an Int")
}
print("totalTime: '\(totalTime)'")
Note: I assumed timeRetrieved
is a UITextField
. The UITextField
text
property is an optional string (though programmatically not allowed to be nil). Therefore, the compiler requires it be unwrapped. I used the nil coalescing operator (??
) to substitute a nil for empty string which does not yield an integer as desired. Here's a post that discusses the optionality of UITextfield.text.
Upvotes: 2
Reputation: 3379
Based on @Graham Perks answer a Swift 3 Version as string extension:
extension String
{
var isNumeric: Bool
{
let range = self.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted)
return (range == nil)
}
}
Usage:
"123".isNumeric // true
"abc".isNumeric // false
Upvotes: 1
Reputation: 321
What i had done was get the value and check if it could convert it, works for me
var enteredText = Int(textfield.text)
if enteredText == nil{
//String entered
}
else{
//Int entered
}
Upvotes: 1
Reputation: 23398
Swift 2 changes this: as both Int("abc") and Int("0") return 0, integer conversion can't be used. You could use this:
class Validation {
static func isStringNumerical(string : String) -> Bool {
// Only allow numbers. Look for anything not a number.
let range = string.rangeOfCharacterFromSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)
return (range == nil)
}
}
It uses a decimalDigitCharacterSet, and can be changed to use whatever character set you want.
func testIsStringNumerical() {
XCTAssertEqual(SignUpLoyaltyViewController.isStringNumerical("123"), true)
XCTAssertEqual(SignUpLoyaltyViewController.isStringNumerical(""), true)
XCTAssertEqual(SignUpLoyaltyViewController.isStringNumerical("12AA"), false)
XCTAssertEqual(SignUpLoyaltyViewController.isStringNumerical("123.4"), false)
}
This is dramatically faster than the Regex answer. (2000 runs, 0.004s vs regex 0.233s)
Upvotes: 5
Reputation: 3581
I really recommend using a REGEX, I was recently trying to validate 10 digit phone numbers using if let _ = Int(stringToTest)...
and on 32 bit hardware, I faced range issues.
func validate(value: String) -> Bool {
let PHONE_REGEX = "\\d{10}"
let phoneTest = NSPredicate(format: "SELF MATCHES %@", PHONE_REGEX)
let result = phoneTest.evaluateWithObject(value)
if result == true {
log.info("'\(self.text!)' is a valid number.")
} else {
log.info("'\(self.text!)' is an invalid number.")
}
return result
}
Upvotes: 0
Reputation: 81
If the number the user has entered is not an integer, convertedNumber will be nil. Just add an else clause in which you can show the alert.
Upvotes: 4