Simple & Fast Card Scanner Library for SwiftUI
SweetCardScanner
SweetCardScanner is a fast and simple Card Scanner library written in Swift, based on CreditCardScanner and Reg libraries by @yhkaplan so that users can pay much more easily by capturing their credit/debit card with the rear camera.
Requirements
- iOS 13.0+ (due to SwiftUI, Vision Framework)
- Tesed on iOS 14.1 with iPhone X
Installation
-
In Xcode, add SwiftPM with the URL of this repository:
https://github.com/aaronLab/SweetCardScanner.git
Usage
-
Add
NSCameraUsageDescription
intoInfo.plist
for Camera Useage Description. -
import SweetCardScanner
on top of theContentView.swift
. -
Now, you can use like
SweetCardScanner()
inside of the body. -
Also, you can use completion clousures, such as
.onDismiss
,.onError
,.onSuccess
right afterSweetCardScanner()
like below. -
If you want to turn off the camera when you move to the result view, you will need to use your own customized navigation status trick. (Check the example below)
var body: some View { SweetCardScanner() .onDismiss { // Do something when the view dismissed. } .onError { error in // The 'error' above gives you 'CreditCardScannerError' struct below. print(error) } .onSuccess { card in // The card above gives you 'CreditCard' struct below. print(card) } }
CreditCardScannerError
public struct CreditCardScannerError: LocalizedError {
public enum Kind { case cameraSetup, photoProcessing, authorizationDenied, capture }
public var kind: Kind
public var underlyingError: Error?
public var errorDescription: String? { (underlyingError as? LocalizedError)?.errorDescription }
}
CreditCard
public struct CreditCard {
public var number: String?
public var name: String?
public var expireDate: DateComponents?
}
Example
You can customize your own view with SweetCardScanner, and SwiftUI like below.
import SwiftUI
import SweetCardScanner
struct ContentView: View {
// MARK: - PROPERTIES
@State var navigationStatus: NavigationStatus? = .ready
@State var card: CreditCard?
// MARK: - BODY
var body: some View {
NavigationView {
GeometryReader { geometry in
ZStack {
NavigationLink(
destination: ResultView(card: card)
.onDisappear {
/*
You will be able to turn on the camera again
when you come back to this view from the result view
by changing your own customized navigation status.
*/
self.navigationStatus = .ready
},
tag: NavigationStatus.pop,
selection: $navigationStatus) {
EmptyView()
}
/*
You will be able to turn off the camera when you move to the result view
with the `if` statement below.
*/
if navigationStatus == .ready {
SweetCardScanner()
.onError { err in
print(err)
}
.onSuccess { card in
self.card = card
self.navigationStatus = .pop
}
}
RoundedRectangle(cornerRadius: 16)
.stroke()
.foregroundColor(.white)
.padding(16)
.frame(width: geometry.size.width, height: geometry.size.width * 0.63, alignment: .center)
} //: ZSTACK
} //: GEOMETRY
} //: NAVIGATION
}
}
// MARK: - NavigationStatus
enum NavigationStatus {
case ready, pop
}