Skip to content

Instantly share code, notes, and snippets.

@rjchatfield
Last active July 8, 2016 10:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rjchatfield/2b274f3075065f1e16bb to your computer and use it in GitHub Desktop.
Save rjchatfield/2b274f3075065f1e16bb to your computer and use it in GitHub Desktop.
Validating PhoneNumber type in Swift with a failable initialiser and an enum (for type safety)
import Foundation
typealias RegexPattern = String
let aussiePhoneNumber = 0424_555_123
let brokePhoneNumber = 0424_555_1231
enum PhoneNumberType: RegexPattern {
// List all regex patterns
case AussieMobile = "(?:\\+?61|0)4(?:[01]\\d{3}|(?:2[1-9]|3[0-57-9]|4[7-9]|5[0-15-9]|6[679]|7[3-8]|8[1478]|9[07-9])\\d{2}|(?:20[2-9]|444|52[0-6]|68[3-9]|70[0-7]|79[01]|820|890|91[0-4])\\d|(?:200[0-3]|201[01]|8984))\\d{4}$"
// case ...
// case ...
// Helper
var regexVal: RegexPattern { return self.rawValue }
}
private extension Int {
func isA(type: PhoneNumberType) -> Bool {
let matches = self.numberOfMatches(regex: type.regexVal)
return matches > 0
}
func numberOfMatches(regex regexPattern: RegexPattern, options: NSRegularExpressionOptions = [], minimumIntegerDigits: Int = 20) -> Int? {
let formatter = NSNumberFormatter()
formatter.minimumIntegerDigits = minimumIntegerDigits
guard let
nStr = formatter.stringFromNumber(self), // Create a n-character string with leading zeros
regex = try? NSRegularExpression(pattern: regexPattern, options: options)
else { return nil }
let len = nStr.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
return regex.numberOfMatchesInString(nStr, options: [], range: NSMakeRange(0, len))
}
}
struct PhoneNumber {
let number: Int
init?(_ number: Int, phoneNumberType: PhoneNumberType) {
guard number.isA(phoneNumberType) else { return nil }
self.number = number
}
}
PhoneNumber(aussiePhoneNumber, phoneNumberType: .AussieMobile) // Optional<PhoneNumber>(PhoneNumber(0424_555_123))
PhoneNumber(brokePhoneNumber, phoneNumberType: .AussieMobile) // nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment