syedfa syedfa - 4 months ago 18
Swift Question

Trying to ensure that method checks for alpha and hyphen characters in Swift

Dear fellow iOS developers:

I have a method that is meant to return a boolean value of true if a string value that it receives contains any combination of either upper/lowercase characters or a hyphen, and returns false if it contains any numbers, or special characters (i.e. contains anything outside of the above character set). I have the following method which unfortunately is not doing that:

let alphaCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"

if self.isNameValid("joe-bYlow") {
print("correct")
} //passes

if self.isNameValid("YYYYY") {
print("correct")
} //passes

if self.isNameValid("8888ja;sdf") {
print ("wrong")
} //fails i.e. it prints "wrong"

if self.isNameValid("__^&^%%%jdjjd") {
print ("wrong")
} //fails i.e. it prints "wrong"

if self.isNameValid("9999") {
print("also wrong")
} //passes

if self.isNameValid("blahBlah8") {
print("wrong")
} //fails i.e. it prints "wrong"

if self.isNameValid("Frank") {
print("correct")
} //passes

func isNameValid(name: String) -> Bool {
let characterSetAllowed = NSCharacterSet(charactersInString: alphaCharacters)
if let _ = name.rangeOfCharacterFromSet(characterSetAllowed, options: .CaseInsensitiveSearch) {
return true
} else {
return false
}
}


Can anyone see what it is I'm doing wrong? Thanks in advance to all who reply.

Answer

You solution is very close to being correct. The logic in your method is checking if ANY character in the name is in alpha characters.

In the case of the string __^&^%%%jdjjd, rangeOfCharacterFromSet is returning the range of the first character it finds in the set. So it returns the range {8, 1} for the first j.

So how do we check for ALL characters in the string? You could loop through every character but that seems like a lot of work.

My solution would be to get the set of characters that you don't want then check that none of the characters are in that set.

func isNameValid(name: String) -> Bool {
    let characterSetNotAllowed = NSCharacterSet(charactersInString: alphaCharacters).invertedSet
    if let _ = name.rangeOfCharacterFromSet(characterSetNotAllowed, options: .CaseInsensitiveSearch) {
        return false
    } else {
        return true
    }
}

Also, thanks for putting your code in a form that could be easily put into a Playground to show the issue. It made it really easy to find the cause.