More iOS Utility Categories!

The more I think about that whole NSMutableCharacterSet thing I'm not happy with my current understanding. I may dig into that more in the near future. But at the moment I'm on my tear of pulling some common/utility code that I use in both Road Trip and Combat Imp into a common repository and putting a Creative Commons license on it. Today's code is adjacent to the NSMutableCharacterSet issue, but not directly related so I can dodge the "Why didn't this crash before I fixed it?" question for now. Quick summary of the problem:

I have many UITextFields where I want "numeric" values entered. I say "numeric" in quotes because it's quite a bit more complex than that. In Road Trip I need to accept strings like "$ 12,345.67". In Combat Imp I have some fields that are "just" numeric (round counter) and some that can take + and - signs (hit points, initiative modifier). All the fields need to take control characters or you can't backspace (and with an external keyboard you can hit things like Shift+Left Arrow to do selection.)

Shameful confession time: my original algorithm for this built a big list of all the characters I would ever want and then inverted the set. The reason for this is that I could call string rangeOfCharacterFromSet and find the first character in a string that was from a set. If the range returned anything other than NSNotFound I knew an illegal character was in the string and I could chuck it. This always seemed super backwards to me. I finally got around to doing what I wanted to do: I wrote a category for NSString that returns YES if all of the characters in the string are members of a set. Now instead of writing:

NSRange foundRange = [string rangeOfCharacterFromSet:nonlegalCharacters]];
if (foundRange.location != NSNotFound) {
    NSLog(@"String is %@, location is %d", string, foundRange.location);
    return NO;
} else {
    return YES;
}

Instead I build the character set of legal characters, cache that, and simply write:

return [string isContainedInCharacterSet:initiativeAndHPLegalCharacterSet];

(Both of these samples live inside textField:shouldChangeCharactersInRange:replacementString methods. Idea is when the user enters text I immediately validate the characters. If it's a 'g' and I only want numbers I reject it immediately. Doesn't even show up on screen.)

Much like the last stupid little helper category I plunked this in its own GitHub. Feel free to grab it if you need. You may notice that there are obvious other tests I could write it this category. I may in the future but for now, this is the only one I need. I'm not pretending to write some sort of comprehensive set of tests here, I'm just providing little snippets of code that I've found useful enough to isolate out and share in projects.