getbouncer / cardscan-ios

A library for scanning credit and debit cards
MIT License
207 stars 66 forks source link

SDK didnt handle scanning error #24

Closed deda9 closed 5 years ago

deda9 commented 5 years ago

While I was trying to handle the scan credit card's failure, there is no firing for the error when it happened:

for instance:

@available(iOS 11.0, *)
    func blockingOcrModel(rawImage: CGImage) {
        let (number, expiry, done, foundNumberInThisScan) = ocr.performWithErrorCorrection(for: rawImage)
        if let number = number {
            self.showCardNumber(number, expiry: expiry?.display())
            if self.includeCardImage && foundNumberInThisScan {
                self.scannedCardImage = UIImage(cgImage: rawImage)
            }
        }

        if done {
            DispatchQueue.main.sync {
                guard let number = number else {
                    return
                }

                if self.calledDelegate {
                    return
                }

                let notification = UINotificationFeedbackGenerator()
                notification.prepare()
                notification.notificationOccurred(.success)
                //let vibrate = SystemSoundID(kSystemSoundID_Vibrate)
                //AudioServicesPlaySystemSound(vibrate)

                self.calledDelegate = true
                let card = CreditCard(number: number)
                card.expiryMonth = expiry.map { String($0.month) }
                card.expiryYear = expiry.map { String($0.year) }
                card.image = self.scannedCardImage
                self.scanDelegate?.userDidScanCard(self, creditCard: card)
            }
        }
    }

Here: It checks if the number is nill (which means there is an error while scanning) then it returns without call self.scanDelegate?.userDidScanCard which means didn't fire the error?

Maybe there is something I'm missing, but I would appreciate if you could clarify how can I handle the error when it happened.

kingst commented 5 years ago

The performWithErrorCorrection function should never return a result with done set to true and number set to nil. The library doesn't really have an explicit error state, it'll keep scanning until it's able to pull out a credit card number.

Are you looking to detect a situation where the user is struggling to scan or are you making sure that you're handling all of the error cases from the library?

deda9 commented 5 years ago

Hallo @kingst Thank you for your reply. Yeah I am trying to track and show error message for the user if the SDK failed to scan the CC, I have been thinking because of the internal code check on the number's value with nil.

Does that (what you described) mean that the scanning is recursive till it gets the result?

kingst commented 5 years ago

Yes, it will scan indefinitely until the user cancels (ie presses the back button). We do have the ability to stop scanning after a period of time, but it's something that you'd implement on your end. Here's how it would work for a 20 second timeout, and you'd put something like this in your app: https://github.com/getbouncer/cardscan-ios/blob/65adaa7918a1607818f0f959dc35b0bf875c830b/Example/CardScan/ViewController.swift#L91-L101

This sort of thing is hard though because you don't know if the user already has their card out or if they need to go to their wallet to get it, and the timing you'd use in both situations is different. Ideally what you'd want is some logic that detects if a card is present but that the model is unable to pull the number off, but that logic is still a ways off. Thus, most people just rely on the user to click the back button in a typical integration, but the option is there if you want to do something more proactive.

deda9 commented 5 years ago

Hallo @kingst Thanks for your reply.

kingst commented 5 years ago

Let me know if you need anything else, but closing this issue for now.