Skip to content

Commit

Permalink
Updated Swift 3 syntax based on the pull request feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibaultKlein authored and DannyVancura committed Nov 29, 2016
1 parent c88f253 commit cfef111
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 64 deletions.
12 changes: 6 additions & 6 deletions CaishenTests/CardNumberValidatorTests.swift
Expand Up @@ -75,37 +75,37 @@ class CardNumberValidatorTests: XCTestCase {
func testValidCards() {
print("Validate Visa")
self.validVisaNumbers.forEach({
XCTAssertEqual(CardTypeRegister.sharedCardTypeRegister.cardTypeFor(number: Number(rawValue: $0)).name, Visa().name)
XCTAssertEqual(CardTypeRegister.sharedCardTypeRegister.cardType(for: Number(rawValue: $0)).name, Visa().name)
XCTAssertValid(Visa().validate(number: Number(rawValue: $0)))
})

print("Validate Amex")
self.validAmexNumbers.forEach({
XCTAssertEqual(CardTypeRegister.sharedCardTypeRegister.cardTypeFor(number: Number(rawValue: $0)).name, AmericanExpress().name)
XCTAssertEqual(CardTypeRegister.sharedCardTypeRegister.cardType(for: Number(rawValue: $0)).name, AmericanExpress().name)
XCTAssertValid(AmericanExpress().validate(number: Number(rawValue: $0)))
})

print("Validate China UnionPay")
self.validChinaUnionPayNumbers.forEach({
XCTAssertEqual(CardTypeRegister.sharedCardTypeRegister.cardTypeFor(number: Number(rawValue: $0)).name, ChinaUnionPay().name)
XCTAssertEqual(CardTypeRegister.sharedCardTypeRegister.cardType(for: Number(rawValue: $0)).name, ChinaUnionPay().name)
XCTAssertValid(ChinaUnionPay().validate(number: Number(rawValue: $0)))
})

print("Validate Diners Club")
self.validDinersClubNumbers.forEach({
XCTAssertEqual(CardTypeRegister.sharedCardTypeRegister.cardTypeFor(number: Number(rawValue: $0)).name, DinersClub().name)
XCTAssertEqual(CardTypeRegister.sharedCardTypeRegister.cardType(for: Number(rawValue: $0)).name, DinersClub().name)
XCTAssertValid(DinersClub().validate(number: Number(rawValue: $0)))
})

print("Validate Discover")
self.validDiscoverNumbers.forEach({
XCTAssertEqual(CardTypeRegister.sharedCardTypeRegister.cardTypeFor(number: Number(rawValue: $0)).name, Discover().name)
XCTAssertEqual(CardTypeRegister.sharedCardTypeRegister.cardType(for: Number(rawValue: $0)).name, Discover().name)
XCTAssertValid(Discover().validate(number: Number(rawValue: $0)))
})

print("Validate JCB")
self.validJCBNumbers.forEach({
XCTAssertEqual(CardTypeRegister.sharedCardTypeRegister.cardTypeFor(number: Number(rawValue: $0)).name, JCB().name, "Card number was interpreted as wrong kind: \($0)")
XCTAssertEqual(CardTypeRegister.sharedCardTypeRegister.cardType(for: Number(rawValue: $0)).name, JCB().name, "Card number was interpreted as wrong kind: \($0)")
XCTAssertValid(JCB().validate(number: Number(rawValue: $0)))
})
}
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
@@ -1,3 +1,3 @@
source 'https://rubygems.org'

gem 'cocoapods'
gem 'cocoapods', '1.1.1'
73 changes: 73 additions & 0 deletions Gemfile.lock
@@ -0,0 +1,73 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (2.3.3)
activesupport (4.2.7.1)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
claide (1.0.1)
cocoapods (1.1.1)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.1, < 2.0)
cocoapods-core (= 1.1.1)
cocoapods-deintegrate (>= 1.0.1, < 2.0)
cocoapods-downloader (>= 1.1.2, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-stats (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.1.1, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored (~> 1.2)
escape (~> 0.0.4)
fourflusher (~> 2.0.1)
gh_inspector (~> 1.0)
molinillo (~> 0.5.1)
nap (~> 1.0)
xcodeproj (>= 1.3.3, < 2.0)
cocoapods-core (1.1.1)
activesupport (>= 4.0.2, < 5)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-deintegrate (1.0.1)
cocoapods-downloader (1.1.2)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-stats (1.0.0)
cocoapods-trunk (1.1.1)
nap (>= 0.8, < 2.0)
netrc (= 0.7.8)
cocoapods-try (1.1.0)
colored (1.2)
escape (0.0.4)
fourflusher (2.0.1)
fuzzy_match (2.0.4)
gh_inspector (1.0.2)
i18n (0.7.0)
json (1.8.3)
minitest (5.9.1)
molinillo (0.5.3)
nanaimo (0.2.0)
nap (1.1.0)
netrc (0.7.8)
thread_safe (0.3.5)
tzinfo (1.2.2)
thread_safe (~> 0.1)
xcodeproj (1.4.1)
CFPropertyList (~> 2.3.3)
activesupport (>= 3)
claide (>= 1.0.1, < 2.0)
colored (~> 1.2)
nanaimo (~> 0.2.0)

PLATFORMS
ruby

DEPENDENCIES
cocoapods (= 1.1.1)

BUNDLED WITH
1.13.6
6 changes: 3 additions & 3 deletions Pod/Classes/Cards/CardTypeRegister.swift
Expand Up @@ -65,7 +65,7 @@ public class CardTypeRegister {
- parameter cardType: The card type that should be removed from this card type register.
*/
public func unregisterCardType(_ cardType: CardType) {
public func unregister(cardType: CardType) {
registeredCardTypes = registeredCardTypes.filter { !$0.isEqual(to: cardType) }
}

Expand All @@ -84,11 +84,11 @@ public class CardTypeRegister {
- important: When creating custom card types, you should make sure, that there are no conflicts in the Issuer Identification Numbers you provide. For example, using [309] to detect a Diners Club card and using [3096] to detect a JCB card will not cause issues as IINs are parsed with the highest numbers first, i.e. the numbers that provide the most context possible, which will return a JCB card in this case. However, no two card types should provide the exact same number (like [309] to detect both a Diners Club card and a JCB card)!
- parameter cardNumber: The card number whose CardType should be determined
- parameter number: The card number whose CardType should be determined
- returns: An instance of UnknownCardType, if no card type matches the Issuer Identification Number of the provided card number or any other card type that matches the card number.
*/
public func cardTypeFor(number: Number) -> CardType {
public func cardType(for number: Number) -> CardType {
for i in (0...min(number.length, 6)).reversed() {
if let substring = number.rawValue[0,i], let substringAsNumber = Int(substring) {
if let firstMatchingCardType = registeredCardTypes.filter({
Expand Down
6 changes: 3 additions & 3 deletions Pod/Classes/Cards/Default Card Types/UnknownCardType.swift
Expand Up @@ -15,18 +15,18 @@ public struct UnknownCardType: CardType {
public let CVCLength = 0
public let identifyingDigits: Set<Int> = []

public func validate(_ number: Number) -> CardValidationResult {
public func validate(number: Number) -> CardValidationResult {
return CardValidationResult.UnknownType
.union(lengthMatchesType(number.length))
.union(numberIsNumeric(number))
.union(numberIsValidLuhn(number))
}

public func validate(_ cvc: CVC) -> CardValidationResult {
public func validate(cvc: CVC) -> CardValidationResult {
return .UnknownType
}

public func validate(_ expiry: Expiry) -> CardValidationResult {
public func validate(expiry: Expiry) -> CardValidationResult {
return .UnknownType
}

Expand Down
22 changes: 11 additions & 11 deletions Pod/Classes/Format/CardNumberFormatter.swift
Expand Up @@ -36,10 +36,10 @@ public final class CardNumberFormatter {
- returns: The unformatted card number string representation.
*/
public func unformattedCardNumber(_ cardNumberString: String) -> String {
return cardNumberString.replacingOccurrences(of: self.separator, with: "")
public func unformat(cardNumber: String) -> String {
return cardNumber.replacingOccurrences(of: self.separator, with: "")
}

/**
Formats the given card number string based on the detected card type.
Expand All @@ -49,8 +49,8 @@ public final class CardNumberFormatter {
*/
public func format(cardNumber: String) -> String {
let regex: NSRegularExpression
let cardType = cardTypeRegister.cardTypeFor(number: Number(rawValue: cardNumber))

let cardType = cardTypeRegister.cardType(for: Number(rawValue: cardNumber))
do {
let groups = cardType.numberGrouping
var pattern = ""
Expand All @@ -67,7 +67,7 @@ public final class CardNumberFormatter {
fatalError("Error when creating regular expression: \(error)")
}

return NSArray(array: self.splitString(cardNumber, withRegex: regex)).componentsJoined(by: self.separator)
return NSArray(array: split(string: cardNumber, with: regex)).componentsJoined(by: self.separator)
}

/**
Expand Down Expand Up @@ -162,10 +162,10 @@ public final class CardNumberFormatter {
- parameter textField: The text field whose text should be changed.
- parameter string: The new string. This might be unformatted or badly formatted and will be formatted properly before being inserted into `textField`.
*/
public func replaceRangeFormatted(_ range: NSRange, inTextField textField: UITextField, withString string: String) {
let newValueUnformatted = self.unformattedCardNumber(NSString(string: textField.text ?? "").replacingCharacters(in: range, with: string))
let oldValueUnformatted = self.unformattedCardNumber(textField.text ?? "")
public func format(range: NSRange, inTextField textField: UITextField, andReplaceWith string: String) {
let newValueUnformatted = unformat(cardNumber: NSString(string: textField.text ?? "").replacingCharacters(in: range, with: string))
let oldValueUnformatted = unformat(cardNumber: textField.text ?? "")

let newValue = format(cardNumber: newValueUnformatted)
let oldValue = textField.text ?? ""

Expand Down Expand Up @@ -193,7 +193,7 @@ public final class CardNumberFormatter {
- returns: An array of all matches found in string for `regex`.
*/
private func splitString(_ string: String, withRegex regex: NSRegularExpression) -> [String] {
private func split(string: String, with regex: NSRegularExpression) -> [String] {
let matches = regex.matches(in: string, options: NSRegularExpression.MatchingOptions(), range: NSMakeRange(0, string.characters.count))
var result = [String]()

Expand Down
2 changes: 1 addition & 1 deletion Pod/Classes/Localization.swift
Expand Up @@ -28,7 +28,7 @@ internal enum Localization: String {
- returns: The accessibility label for the provided text field.
*/
static func accessibilityLabelForTextField(_ textField: UITextField, comment: String? = nil) -> String? {
static func accessibilityLabel(for textField: UITextField, with comment: String? = nil) -> String? {
switch textField {
case is NumberInputTextField:
return Localization.NumberInputTextFieldAccessibilityLabel.localizedStringWithComment(comment)
Expand Down
12 changes: 6 additions & 6 deletions Pod/Classes/UI/CardTextField+CardInfoTextFieldDelegate.swift
Expand Up @@ -89,20 +89,20 @@ extension CardTextField: CardInfoTextFieldDelegate {
}

// MARK: Accessibility

/**
Add an observer to listen to the event of UIAccessibilityAnnouncementDidFinishNotification, and then post an accessibility
notification to user that the entered expiration date has already expired.
The reason why can't we just post an accessbility notification is that only the last accessibility notification would be read to users.
As each time users input something there will be an accessibility notification from the system which will always replace what we have
As each time users input something there will be an accessibility notification from the system which will always replace what we have
posted here. Thus we need to listen to the notification from the system first, wait until it is finished, and post ours afterwards.
*/
private func addDateInvalidityObserver() {
NotificationCenter.default.addObserver(self,
selector: #selector(notifyExpiryInvalidity),
name: NSNotification.Name.UIAccessibilityAnnouncementDidFinish,
object: nil)
selector: #selector(notifyExpiryInvalidity),
name: NSNotification.Name.UIAccessibilityAnnouncementDidFinish,
object: nil)
}

/**
Expand Down
2 changes: 1 addition & 1 deletion Pod/Classes/UI/CardTextField+PrefillInformation.swift
Expand Up @@ -33,7 +33,7 @@ public extension CardTextField {
}

if let cardNumber = number, let numberInputTextField = numberInputTextField {
numberInputTextField.prefill(text: cardNumber)
numberInputTextField.prefill(cardNumber)

// With a new card number comes a new card type - pass this card type to `cvcTextField`
cvcTextField?.cardType = cardType
Expand Down
36 changes: 18 additions & 18 deletions Pod/Classes/UI/CardTextField.swift
Expand Up @@ -207,7 +207,7 @@ public class CardTextField: UITextField, NumberInputTextFieldDelegate {
return nil
}

return cardTypeRegister.cardTypeFor(number: number)
return cardTypeRegister.cardType(for: number)
}

internal var hideExpiryTextFields: Bool = false {
Expand Down Expand Up @@ -288,7 +288,7 @@ public class CardTextField: UITextField, NumberInputTextFieldDelegate {
firstObjectInNib.frame = bounds
addSubview(firstObjectInNib)

cardImageView?.image = cardTypeImageStore.imageFor(UnknownCardType())
cardImageView?.image = cardTypeImageStore.image(for: UnknownCardType())
cardImageView?.layer.cornerRadius = 5.0
cardImageView?.layer.shadowColor = UIColor.black.cgColor
cardImageView?.layer.shadowRadius = 2
Expand Down Expand Up @@ -380,20 +380,20 @@ public class CardTextField: UITextField, NumberInputTextFieldDelegate {
Adds voice over accessibility support for all text fields
*/
private func setupAccessibilityLabels() {
setupAccessibilityLabelFor(textField: numberInputTextField)
setupAccessibilityLabelFor(textField: cvcTextField)
setupAccessibilityLabelFor(textField: monthTextField)
setupAccessibilityLabelFor(textField: yearTextField)
setupAccessibilityLabel(for: numberInputTextField)
setupAccessibilityLabel(for: cvcTextField)
setupAccessibilityLabel(for: monthTextField)
setupAccessibilityLabel(for: yearTextField)
}

/**
Adds voice over accessibility support for a particular text fields
- parameter textField: a text field that needs support for voice over accessibility
*/
private func setupAccessibilityLabelFor(textField: UITextField) {
textField.accessibilityLabel = Localization.accessibilityLabelForTextField(textField,
comment: "Accessibility label for \(String(describing: textField))")
private func setupAccessibilityLabel(for textField: UITextField) {
textField.accessibilityLabel = Localization.accessibilityLabel(for: textField,
with: "Accessibility label for \(String(describing: textField))")
}

/**
Expand Down Expand Up @@ -496,16 +496,16 @@ public class CardTextField: UITextField, NumberInputTextFieldDelegate {
@objc public func numberInputTextFieldDidChangeText(_ numberInputTextField: NumberInputTextField) {
showCardImage()
notifyDelegate()
hideExpiryTextFields = !cardTypeRegister.cardTypeFor(number: numberInputTextField.cardNumber).requiresExpiry
hideCVCTextField = !cardTypeRegister.cardTypeFor(number: numberInputTextField.cardNumber).requiresCVC
hideExpiryTextFields = !cardTypeRegister.cardType(for: numberInputTextField.cardNumber).requiresExpiry
hideCVCTextField = !cardTypeRegister.cardType(for: numberInputTextField.cardNumber).requiresCVC
}

public func numberInputTextFieldDidComplete(_ numberInputTextField: NumberInputTextField) {
moveCardNumberOutAnimated()

notifyDelegate()
hideExpiryTextFields = !cardTypeRegister.cardTypeFor(number: numberInputTextField.cardNumber).requiresExpiry
hideCVCTextField = !cardTypeRegister.cardTypeFor(number: numberInputTextField.cardNumber).requiresCVC
hideExpiryTextFields = !cardTypeRegister.cardType(for: numberInputTextField.cardNumber).requiresExpiry
hideCVCTextField = !cardTypeRegister.cardType(for: numberInputTextField.cardNumber).requiresCVC
if hideExpiryTextFields && hideCVCTextField {
return
} else if hideExpiryTextFields {
Expand All @@ -521,8 +521,8 @@ public class CardTextField: UITextField, NumberInputTextFieldDelegate {
Displays the card image for the currently detected card type in the card text field's `cardImageView`.
*/
internal func showCardImage() {
let cardType = cardTypeRegister.cardTypeFor(number: numberInputTextField.cardNumber)
let cardTypeImage = cardTypeImageStore.imageFor(cardType)
let cardType = cardTypeRegister.cardType(for: numberInputTextField.cardNumber)
let cardTypeImage = cardTypeImageStore.image(for: cardType)

cardImageView?.image = cardTypeImage
}
Expand All @@ -531,8 +531,8 @@ public class CardTextField: UITextField, NumberInputTextFieldDelegate {
Displays the CVC image for the currently detected card type in the card text field's `cardImageView`.
*/
internal func showCVCImage() {
let cardType = cardTypeRegister.cardTypeFor(number: numberInputTextField.cardNumber)
let cvcImage = cardTypeImageStore.cvcImageFor(cardType)
let cardType = cardTypeRegister.cardType(for: numberInputTextField.cardNumber)
let cvcImage = cardTypeImageStore.cvcImage(for: cardType)

cardImageView?.image = cvcImage
cvcTextField?.cardType = cardType
Expand Down
10 changes: 5 additions & 5 deletions Pod/Classes/UI/CardTypeImageStore.swift
Expand Up @@ -18,7 +18,7 @@ public protocol CardTypeImageStore {
- returns: The image for the specified card type or nil, if no image was provided for this card type.
*/
func imageFor(_ cardType: CardType) -> UIImage?
func image(for cardType: CardType) -> UIImage?

/**
Provides an image for the CVC of a specific card type. The position of a CVC on a card may vary based on the card issuer, so that different card types may provide different images to indicate the location of the CVC on the card. This image will be shown in a `CardTextField`'s image view once the user starts entering the CVC.
Expand All @@ -27,17 +27,17 @@ public protocol CardTypeImageStore {
- returns: The image for the CVC of the specified card type or nil, if no image was provided for this card type.
*/
func cvcImageFor(_ cardType: CardType) -> UIImage?
func cvcImage(for cardType: CardType) -> UIImage?

}

extension Bundle: CardTypeImageStore {
public func imageFor(_ cardType: CardType) -> UIImage? {

public func image(for cardType: CardType) -> UIImage? {
return UIImage(named: cardType.name, in: self, compatibleWith: nil)
}

public func cvcImageFor(_ cardType: CardType) -> UIImage? {
public func cvcImage(for cardType: CardType) -> UIImage? {
let cvcImageName: String
if cardType.isEqual(to: AmericanExpress()) {
cvcImageName = "AmexCVC"
Expand Down

0 comments on commit cfef111

Please sign in to comment.