├── .npmignore ├── .gitattributes ├── example ├── ios │ ├── .gitignore │ ├── example │ │ ├── Images.xcassets │ │ │ ├── Contents.json │ │ │ ├── bouncer_scan_back.imageset │ │ │ │ ├── outline_arrow_back_white_36pt_1x.png │ │ │ │ ├── outline_arrow_back_white_36pt_2x.png │ │ │ │ ├── outline_arrow_back_white_36pt_3x.png │ │ │ │ └── Contents.json │ │ │ ├── bouncer_scan_flash_on.imageset │ │ │ │ ├── outline_flashlight_on_white_36pt_1x.png │ │ │ │ ├── outline_flashlight_on_white_36pt_2x.png │ │ │ │ ├── outline_flashlight_on_white_36pt_3x.png │ │ │ │ └── Contents.json │ │ │ ├── bouncer_scan_flash_off.imageset │ │ │ │ ├── outline_flashlight_off_white_36pt_1x.png │ │ │ │ ├── outline_flashlight_off_white_36pt_2x.png │ │ │ │ ├── outline_flashlight_off_white_36pt_3x.png │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── File.swift │ │ ├── AppDelegate.h │ │ ├── main.m │ │ ├── AppDelegate.m │ │ ├── Info.plist │ │ └── Base.lproj │ │ │ └── LaunchScreen.xib │ ├── example-Bridging-Header.h │ ├── example.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── Podfile │ └── example.xcodeproj │ │ ├── xcshareddata │ │ └── xcschemes │ │ │ ├── example.xcscheme │ │ │ └── example-tvOS.xcscheme │ │ └── project.pbxproj ├── app.json ├── .gitignore ├── babel.config.js ├── android │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── values │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ └── mipmap-xxxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── getbouncer │ │ │ │ │ │ └── example │ │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ │ └── MainApplication.java │ │ │ │ └── AndroidManifest.xml │ │ │ └── debug │ │ │ │ └── AndroidManifest.xml │ │ ├── build_defs.bzl │ │ ├── proguard-rules.pro │ │ ├── BUCK │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── keystores │ │ ├── debug.keystore.properties │ │ └── BUCK │ ├── settings.gradle │ ├── gradle.properties │ ├── build.gradle │ ├── gradlew.bat │ └── gradlew ├── index.js ├── metro.config.js ├── package.json └── App.js ├── android ├── gradle.properties ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── getbouncer │ │ ├── RNCardscanPackage.java │ │ └── RNCardscanModule.java ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew.bat ├── build.gradle └── gradlew ├── docs └── images │ └── demo.gif ├── index.js ├── ios ├── RNCardScan-Bridging-Header.h ├── RNCardscan.m ├── UIColor+Hex.swift ├── RNCardScanStyle.swift ├── RNCardscan.xcodeproj │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── RNCardScan.xcscheme │ └── project.pbxproj ├── RNCardScan.swift └── RNCardScanViewController.swift ├── .gitignore ├── react-native-cardscan.podspec ├── .github └── workflows │ ├── android_lint.yml │ ├── android_unit_test.yml │ └── release.yml ├── package.json ├── CODEOWNERS ├── scripts └── examples_postinstall.js ├── README.md ├── CHANGELOG.md ├── Contributor License Agreement └── LICENSE /.npmignore: -------------------------------------------------------------------------------- 1 | example 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | Podfile.lock 2 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | android.useAndroidX = true 2 | 3 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "displayName": "example" 4 | } -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # iOS 2 | ios/Pods 3 | package-lock.json 4 | 5 | # Bundle 6 | *.tgz 7 | -------------------------------------------------------------------------------- /docs/images/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/docs/images/demo.gif -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | example 3 | 4 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import { NativeModules } from 'react-native'; 2 | 3 | const { RNCardscan } = NativeModules; 4 | 5 | export default RNCardscan; 6 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/ios/example-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = "debug", 3 | properties = "debug.keystore.properties", 4 | store = "debug.keystore", 5 | visibility = [ 6 | "PUBLIC", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /example/ios/example/File.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // example 4 | // 5 | // Created by Stefano Chiesa Suryanto on 11/7/19. 6 | // Copyright © 2019 Facebook. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | -------------------------------------------------------------------------------- /ios/RNCardScan-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | #import 6 | #import 7 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import App from './App'; 7 | import {name as appName} from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'example' 2 | 3 | include ':react-native-cardscan' 4 | project(':react-native-cardscan').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-cardscan/android') 5 | 6 | include ':app' 7 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/bouncer_scan_back.imageset/outline_arrow_back_white_36pt_1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/ios/example/Images.xcassets/bouncer_scan_back.imageset/outline_arrow_back_white_36pt_1x.png -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/bouncer_scan_back.imageset/outline_arrow_back_white_36pt_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/ios/example/Images.xcassets/bouncer_scan_back.imageset/outline_arrow_back_white_36pt_2x.png -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/bouncer_scan_back.imageset/outline_arrow_back_white_36pt_3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/ios/example/Images.xcassets/bouncer_scan_back.imageset/outline_arrow_back_white_36pt_3x.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/bouncer_scan_flash_on.imageset/outline_flashlight_on_white_36pt_1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/ios/example/Images.xcassets/bouncer_scan_flash_on.imageset/outline_flashlight_on_white_36pt_1x.png -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/bouncer_scan_flash_on.imageset/outline_flashlight_on_white_36pt_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/ios/example/Images.xcassets/bouncer_scan_flash_on.imageset/outline_flashlight_on_white_36pt_2x.png -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/bouncer_scan_flash_on.imageset/outline_flashlight_on_white_36pt_3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/ios/example/Images.xcassets/bouncer_scan_flash_on.imageset/outline_flashlight_on_white_36pt_3x.png -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/bouncer_scan_flash_off.imageset/outline_flashlight_off_white_36pt_1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/ios/example/Images.xcassets/bouncer_scan_flash_off.imageset/outline_flashlight_off_white_36pt_1x.png -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/bouncer_scan_flash_off.imageset/outline_flashlight_off_white_36pt_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/ios/example/Images.xcassets/bouncer_scan_flash_off.imageset/outline_flashlight_off_white_36pt_2x.png -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/bouncer_scan_flash_off.imageset/outline_flashlight_off_white_36pt_3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getbouncer/react-native-cardscan/HEAD/example/ios/example/Images.xcassets/bouncer_scan_flash_off.imageset/outline_flashlight_off_white_36pt_3x.png -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue May 19 16:04:26 PDT 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-all.zip 7 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue May 19 18:32:20 PDT 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-all.zip 7 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | module.exports = { 9 | transformer: { 10 | getTransformOptions: async () => ({ 11 | transform: { 12 | experimentalImportSupport: false, 13 | inlineRequires: false, 14 | }, 15 | }), 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 2 | require_relative '../node_modules/react-native/scripts/react_native_pods' 3 | 4 | platform :ios, '11.0' 5 | 6 | target 'example' do 7 | pod 'CardScan', '~> 2.0.9' 8 | pod 'react-native-cardscan', :path => '../node_modules/react-native-cardscan' 9 | 10 | config = use_native_modules! 11 | use_react_native!(:path => config["reactNativePath"]) 12 | end 13 | 14 | -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (nonatomic, strong) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /example/ios/example/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/getbouncer/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.getbouncer.example; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "example"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # node.js 6 | # 7 | node_modules/ 8 | npm-debug.log 9 | yarn-error.log 10 | 11 | # Xcode 12 | # 13 | build/ 14 | *.pbxuser 15 | !default.pbxuser 16 | *.mode1v3 17 | !default.mode1v3 18 | *.mode2v3 19 | !default.mode2v3 20 | *.perspectivev3 21 | !default.perspectivev3 22 | xcuserdata 23 | *.xccheckout 24 | *.moved-aside 25 | DerivedData 26 | *.hmap 27 | *.ipa 28 | *.xcuserstate 29 | project.xcworkspace 30 | 31 | # BUCK 32 | buck-out/ 33 | \.buckd/ 34 | *.keystore 35 | 36 | # Android/IntelliJ 37 | # 38 | build/ 39 | .idea 40 | .gradle 41 | local.properties 42 | *.iml 43 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/bouncer_scan_flash_off.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "outline_flashlight_off_white_36pt_1x.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "outline_flashlight_off_white_36pt_2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "outline_flashlight_off_white_36pt_3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/RNCardscan.m: -------------------------------------------------------------------------------- 1 | // 2 | // RNCardScan.m 3 | // RNCardScan 4 | // 5 | // Created by Jaime Park on 9/23/21. 6 | // Copyright © 2021 Facebook. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "React/RCTBridgeModule.h" 11 | 12 | @interface RCT_EXTERN_MODULE(RNCardscan, NSObject) 13 | RCT_EXTERN_METHOD(isSupportedAsync:(RCTPromiseResolveBlock)resolve 14 | :(RCTPromiseRejectBlock)reject) 15 | RCT_EXTERN_METHOD(scan:(RCTPromiseResolveBlock)resolve 16 | :(RCTPromiseRejectBlock)reject) 17 | RCT_EXTERN_METHOD(setiOSScanViewStyle:(NSDictionary)styleDictionary) 18 | @end 19 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/bouncer_scan_back.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "outline_arrow_back_white_36pt_1x.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "outline_arrow_back_white_36pt_2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "outline_arrow_back_white_36pt_3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /example/android/app/build_defs.bzl: -------------------------------------------------------------------------------- 1 | """Helper definitions to glob .aar and .jar targets""" 2 | 3 | def create_aar_targets(aarfiles): 4 | for aarfile in aarfiles: 5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] 6 | lib_deps.append(":" + name) 7 | android_prebuilt_aar( 8 | name = name, 9 | aar = aarfile, 10 | ) 11 | 12 | def create_jar_targets(jarfiles): 13 | for jarfile in jarfiles: 14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] 15 | lib_deps.append(":" + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/bouncer_scan_flash_on.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "outline_flashlight_on_white_36pt_1x.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "outline_flashlight_on_white_36pt_2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "outline_flashlight_on_white_36pt_3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /android/src/main/java/com/getbouncer/RNCardscanPackage.java: -------------------------------------------------------------------------------- 1 | package com.getbouncer; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | import com.facebook.react.ReactPackage; 7 | import com.facebook.react.bridge.NativeModule; 8 | import com.facebook.react.bridge.ReactApplicationContext; 9 | import com.facebook.react.uimanager.ViewManager; 10 | 11 | public class RNCardscanPackage implements ReactPackage { 12 | 13 | @Override 14 | public List createNativeModules(ReactApplicationContext reactContext) { 15 | return Collections.singletonList(new RNCardscanModule(reactContext)); 16 | } 17 | 18 | @Override 19 | public List createViewManagers(ReactApplicationContext reactContext) { 20 | return Collections.emptyList(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /react-native-cardscan.podspec: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, "package.json"))) 4 | 5 | Pod::Spec.new do |s| 6 | s.name = "react-native-cardscan" 7 | s.version = package["version"] 8 | s.summary = package["description"] 9 | s.description = <<-DESC 10 | react-native-cardscan 11 | DESC 12 | s.homepage = "https://github.com/getbouncer/react-native-cardscan" 13 | s.license = "MIT" 14 | s.authors = { "Stefano Suryanto" => "stefanocsuryanto@gmail.com" } 15 | s.platforms = { :ios => "9.0", :tvos => "10.0" } 16 | s.source = { :git => "https://github.com/getbouncer/react-native-cardscan.git", :tag => "#{s.version}" } 17 | 18 | s.source_files = "ios/**/*.{h,m,swift}" 19 | s.requires_arc = true 20 | 21 | s.dependency "React-Core" 22 | s.dependency "CardScan", '~> 2.0.9' 23 | end 24 | 25 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | android.useAndroidX=true 20 | android.enableJetifier=true 21 | -------------------------------------------------------------------------------- /.github/workflows/android_lint.yml: -------------------------------------------------------------------------------- 1 | name: Android Lint 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | android-lint: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: checkout 16 | uses: actions/checkout@v2 17 | 18 | - name: set up JDK 1.8 19 | uses: actions/setup-java@v1 20 | with: 21 | java-version: 1.8 22 | 23 | - name: dependencies 24 | run: | 25 | npm install 26 | cd example 27 | npm install 28 | cd .. 29 | 30 | - name: lint 31 | run: | 32 | cd android 33 | ./gradlew lint 34 | cd .. 35 | 36 | - name: example-lint 37 | run: | 38 | cd example/android 39 | ./gradlew lint 40 | cd ../.. 41 | 42 | - name: upload-artifacts 43 | uses: actions/upload-artifact@v2 44 | if: failure() 45 | with: 46 | name: test-report 47 | path: ${{ github.workspace }}/*/build/reports/ 48 | -------------------------------------------------------------------------------- /.github/workflows/android_unit_test.yml: -------------------------------------------------------------------------------- 1 | name: Android Unit Tests 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | android-unit-test: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: checkout 16 | uses: actions/checkout@v2 17 | 18 | - name: set up JDK 1.8 19 | uses: actions/setup-java@v1 20 | with: 21 | java-version: 1.8 22 | 23 | - name: dependencies 24 | run: | 25 | npm install 26 | cd example 27 | npm install 28 | cd .. 29 | 30 | - name: test 31 | run: | 32 | cd android 33 | ./gradlew test 34 | cd .. 35 | 36 | - name: example-test 37 | run: | 38 | cd example/android 39 | ./gradlew test 40 | cd ../.. 41 | 42 | - name: upload-artifacts 43 | uses: actions/upload-artifact@v2 44 | if: failure() 45 | with: 46 | name: test-report 47 | path: ${{ github.workspace }}/*/build/reports/ 48 | -------------------------------------------------------------------------------- /ios/UIColor+Hex.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+Hex.swift 3 | // RNCardscan 4 | // 5 | // Created by Jaime Park on 9/22/21. 6 | // Copyright © 2021 Facebook. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIColor { 12 | public convenience init(hexString: String) { 13 | let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) 14 | var int = UInt64() 15 | Scanner(string: hex).scanHexInt64(&int) 16 | let a, r, g, b: UInt64 17 | switch hex.count { 18 | case 3: // RGB (12-bit) 19 | (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) 20 | case 6: // RGB (24-bit) 21 | (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) 22 | case 8: // ARGB (32-bit) 23 | (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) 24 | default: 25 | (a, r, g, b) = (255, 0, 0, 0) 26 | } 27 | self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 13 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "29.0.3" 6 | minSdkVersion = 21 7 | compileSdkVersion = 29 8 | targetSdkVersion = 29 9 | supportLibVersion = "29.0.0" 10 | } 11 | repositories { 12 | google() 13 | jcenter() 14 | } 15 | dependencies { 16 | classpath("com.android.tools.build:gradle:4.0.0") 17 | 18 | // NOTE: Do not place your application dependencies here; they belong 19 | // in the individual module build.gradle files 20 | } 21 | } 22 | 23 | allprojects { 24 | repositories { 25 | mavenLocal() 26 | maven { 27 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 28 | url "$rootDir/../node_modules/react-native/android" 29 | } 30 | maven { 31 | // Android JSC is installed from npm 32 | url "$rootDir/../node_modules/jsc-android/dist" 33 | } 34 | google() 35 | jcenter() 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-cardscan", 3 | "title": "React Native Cardscan", 4 | "version": "2.0.0", 5 | "description": "This library provides payment card scanning functionality for your react-native app.", 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/getbouncer/react-native-cardscan.git", 13 | "baseUrl": "https://github.com/getbouncer/react-native-cardscan" 14 | }, 15 | "homepage": "https://cardscan.io", 16 | "keywords": [ 17 | "react-native", 18 | "card", 19 | "scan", 20 | "cardscan", 21 | "payment", 22 | "mobile", 23 | "android", 24 | "ios" 25 | ], 26 | "author": { 27 | "name": "Stefano Suryanto, Adam Wushensky, and Jaime Park", 28 | "email": "support@getbouncer.com" 29 | }, 30 | "license": "SEE LICENSE IN LICENSE FILE", 31 | "licenseFilename": "LICENSE", 32 | "readmeFilename": "README.md", 33 | "peerDependencies": { 34 | "react": ">=16.8.1 <18.x", 35 | "react-native": ">=0.59.0-rc.0 <1.0.x" 36 | }, 37 | "devDependencies": { 38 | "react": "^17.0.1", 39 | "react-native": "^0.64.0" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ios/RNCardScanStyle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RNCardScanStyle.swift 3 | // RNCardscan 4 | // 5 | // Created by Jaime Park on 9/22/21. 6 | // Copyright © 2021 Facebook. All rights reserved. 7 | // 8 | 9 | import CoreGraphics 10 | import Foundation 11 | 12 | public enum TorchPosition: Int { 13 | case topRight = 0 14 | case bottom = 1 15 | } 16 | 17 | public struct RNCardScanStyle: Decodable { 18 | var backButtonTintColor: String? 19 | var backButtonText: String? 20 | 21 | var backgroundColor: String? 22 | var backgroundColorOpacity: CGFloat? 23 | 24 | var cardDetailExpiryTextColor: String? 25 | var cardDetailNameTextColor: String? 26 | var cardDetailNumberTextColor: String? 27 | 28 | var descriptionHeaderText: String? 29 | var descriptionHeaderTextColor: String? 30 | var descriptionHeaderTextFont: String? 31 | var descriptionHeaderTextSize: CGFloat? 32 | 33 | var enableCameraPermissionText: String? 34 | var enableCameraPermissionTextColor: String? 35 | var enableCameraPermissionTextFont: String? 36 | var enableCameraPermissionTextSize: CGFloat? 37 | 38 | var instructionText: String? 39 | var instructionTextFont: String? 40 | var instructionTextColor: String? 41 | var instructionTextSize: CGFloat? 42 | 43 | var roiBorderColor: String? 44 | var roiCornerRadius: CGFloat? 45 | 46 | var torchButtonTintColor: String? 47 | var torchButtonPosition: Int? 48 | var torchButtonText: String? 49 | } 50 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # This is a comment. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # These owners will be the default owners for everything in 5 | # the repo. Unless a later match takes precedence, 6 | # @global-owner1 and @global-owner2 will be requested for 7 | # review when someone opens a pull request. 8 | * @xsl @kingst-stripe @awush-stripe @jaimepark-stripe 9 | 10 | # Order is important; the last matching pattern takes the most 11 | # precedence. When someone opens a pull request that only 12 | # modifies JS files, only @js-owner and not the global 13 | # owner(s) will be requested for a review. 14 | # *.js @js-owner 15 | 16 | # You can also use email addresses if you prefer. They'll be 17 | # used to look up users just like we do for commit author 18 | # emails. 19 | # *.go docs@example.com 20 | 21 | # In this example, @doctocat owns any files in the build/logs 22 | # directory at the root of the repository and any of its 23 | # subdirectories. 24 | # /build/logs/ @doctocat 25 | 26 | # The `docs/*` pattern will match files like 27 | # `docs/getting-started.md` but not further nested files like 28 | # `docs/build-app/troubleshooting.md`. 29 | # docs/* docs@example.com 30 | 31 | # In this example, @octocat owns any file in an apps directory 32 | # anywhere in your repository. 33 | # apps/ @octocat 34 | 35 | # In this example, @doctocat owns any file in the `/docs` 36 | # directory in the root of your repository. 37 | # /docs/ @doctocat 38 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-cardscan-example", 3 | "title": "React Native CardScan Example", 4 | "version": "0.0.1", 5 | "description": "This app demonstrates the capabilites of the react-native-cardscan library.", 6 | "private": true, 7 | "scripts": { 8 | "preinstall": "npm pack ..", 9 | "start": "node node_modules/react-native/local-cli/cli.js start", 10 | "test": "jest", 11 | "postinstall": "node ../scripts/examples_postinstall.js node_modules/react-native-cardscan" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/getbouncer/react-native-cardscan.git", 16 | "baseUrl": "https://github.com/getbouncer/react-native-cardscan" 17 | }, 18 | "homepage": "https://cardscan.io", 19 | "author": { 20 | "name": "Stefano Suryanto, Adam Wushensky, and Jaime Park", 21 | "email": "support@getbouncer.com" 22 | }, 23 | "dependencies": { 24 | "hermesvm": "^0.1.1", 25 | "jsc-android": "^241213.1.0", 26 | "react": "^17.0.1", 27 | "react-native": "^0.64.0", 28 | "react-native-cardscan": "file:react-native-cardscan-2.0.0.tgz", 29 | "react-native-credit-card-input-view": "^0.0.6" 30 | }, 31 | "devDependencies": { 32 | "@babel/core": "^7.11.6", 33 | "@babel/runtime": "^7.11.2", 34 | "babel-jest": "^24.9.0", 35 | "jest": "^24.9.0", 36 | "metro-react-native-babel-preset": "^0.57.0" 37 | }, 38 | "jest": { 39 | "preset": "react-native" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /example/android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") 12 | 13 | lib_deps = [] 14 | 15 | create_aar_targets(glob(["libs/*.aar"])) 16 | 17 | create_jar_targets(glob(["libs/*.jar"])) 18 | 19 | android_library( 20 | name = "all-libs", 21 | exported_deps = lib_deps, 22 | ) 23 | 24 | android_library( 25 | name = "app-code", 26 | srcs = glob([ 27 | "src/main/java/**/*.java", 28 | ]), 29 | deps = [ 30 | ":all-libs", 31 | ":build_config", 32 | ":res", 33 | ], 34 | ) 35 | 36 | android_build_config( 37 | name = "build_config", 38 | package = "com.getbouncer.example", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.getbouncer.example", 44 | res = "src/main/res", 45 | ) 46 | 47 | android_binary( 48 | name = "app", 49 | keystore = "//android/keystores:debug", 50 | manifest = "src/main/AndroidManifest.xml", 51 | package_type = "debug", 52 | deps = [ 53 | ":app-code", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/getbouncer/example/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.getbouncer.example; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.react.ReactApplication; 6 | import com.getbouncer.RNCardscanPackage; 7 | import com.facebook.react.ReactNativeHost; 8 | import com.facebook.react.ReactPackage; 9 | import com.facebook.react.shell.MainReactPackage; 10 | import com.facebook.soloader.SoLoader; 11 | import com.getbouncer.RNCardscanModule; 12 | 13 | import java.util.Arrays; 14 | import java.util.List; 15 | 16 | public class MainApplication extends Application implements ReactApplication { 17 | 18 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 19 | @Override 20 | public boolean getUseDeveloperSupport() { 21 | return BuildConfig.DEBUG; 22 | } 23 | 24 | @Override 25 | protected List getPackages() { 26 | return Arrays.asList( 27 | new MainReactPackage(), 28 | new RNCardscanPackage() 29 | ); 30 | } 31 | 32 | @Override 33 | protected String getJSMainModuleName() { 34 | return "index"; 35 | } 36 | }; 37 | 38 | @Override 39 | public ReactNativeHost getReactNativeHost() { 40 | return mReactNativeHost; 41 | } 42 | 43 | @Override 44 | public void onCreate() { 45 | super.onCreate(); 46 | SoLoader.init(this, /* native exopackage */ false); 47 | RNCardscanModule.apiKey = ""; 48 | RNCardscanModule.enableEnterCardManually = true; 49 | RNCardscanModule.enableNameExtraction = true; 50 | RNCardscanModule.enableExpiryExtraction = true; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "AppDelegate.h" 9 | 10 | #import 11 | #import 12 | #import 13 | 14 | @import CardScan; 15 | 16 | @implementation AppDelegate 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 19 | { 20 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; 21 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 22 | moduleName:@"example" 23 | initialProperties:nil]; 24 | 25 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 26 | 27 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 28 | UIViewController *rootViewController = [UIViewController new]; 29 | rootViewController.view = rootView; 30 | self.window.rootViewController = rootViewController; 31 | [self.window makeKeyAndVisible]; 32 | 33 | [SimpleScanViewController configureWithApiKey:@"ENTER_API_KEY"]; 34 | 35 | return YES; 36 | } 37 | 38 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 39 | { 40 | #if DEBUG 41 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 42 | #else 43 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 44 | #endif 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /example/ios/example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | NSExceptionDomains 32 | 33 | localhost 34 | 35 | NSExceptionAllowsInsecureHTTPLoads 36 | 37 | 38 | 39 | 40 | NSCameraUsageDescription 41 | We need access to your camera to scan your card 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIRequiredDeviceCapabilities 45 | 46 | armv7 47 | 48 | UISupportedInterfaceOrientations 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationLandscapeLeft 52 | UIInterfaceOrientationLandscapeRight 53 | 54 | UIViewControllerBasedStatusBarAppearance 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /ios/RNCardscan.xcodeproj/xcshareddata/xcschemes/RNCardScan.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /example/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem http://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /ios/RNCardScan.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RNCardScan.swift 3 | // RNCardScan 4 | // 5 | // Created by Jaime Park on 9/22/21. 6 | // Copyright © 2021 Facebook. All rights reserved. 7 | // 8 | 9 | import CardScan 10 | import Foundation 11 | import UIKit 12 | 13 | @available(iOS 11.2, *) 14 | @objc(RNCardscan) 15 | class RNCardScan: NSObject { 16 | var resolve: RCTPromiseResolveBlock? 17 | var styleDictionary: NSDictionary? 18 | 19 | override init() { 20 | super.init() 21 | } 22 | 23 | @objc class func requiresMainQueueSetup() -> Bool { 24 | return true 25 | } 26 | 27 | @objc func isSupportedAsync( 28 | _ resolve: RCTPromiseResolveBlock, 29 | _ reject: RCTPromiseRejectBlock 30 | ) -> Void { 31 | if true { 32 | resolve([SimpleScanViewController.isCompatible()]) 33 | } else { 34 | reject(nil, nil, nil) 35 | } 36 | } 37 | 38 | @objc func setiOSScanViewStyle(_ styleDictionary: NSDictionary) { 39 | self.styleDictionary = styleDictionary 40 | } 41 | 42 | @objc func scan( 43 | _ resolve: @escaping RCTPromiseResolveBlock, 44 | _ reject: RCTPromiseRejectBlock 45 | ) -> Void { 46 | self.resolve = resolve 47 | 48 | DispatchQueue.main.async { 49 | let topViewController = self.getTopViewController() 50 | let vc = RNCardScanViewController(viewStyle: self.styleDictionary) 51 | vc.delegate = self 52 | topViewController?.present(vc, animated: true, completion: nil) 53 | } 54 | } 55 | 56 | func getTopViewController() -> UIViewController? { 57 | guard var topViewController = UIApplication.shared.keyWindow?.rootViewController else { 58 | return nil 59 | } 60 | 61 | while let nextViewController = topViewController.presentedViewController { 62 | topViewController = nextViewController 63 | } 64 | 65 | return topViewController 66 | } 67 | } 68 | 69 | @available(iOS 11.2, *) 70 | extension RNCardScan: SimpleScanDelegate { 71 | // MARK: -SimpleScanDelegate implementation 72 | func userDidCancelSimple(_ scanViewController: SimpleScanViewController) { 73 | if let topViewController = getTopViewController() { 74 | topViewController.dismiss(animated: true, completion: nil) 75 | } 76 | 77 | if let resolve = resolve { 78 | resolve([ 79 | "action": "canceled", 80 | "canceledReason": "user_canceled" 81 | ]) 82 | } 83 | } 84 | 85 | func userDidScanCardSimple(_ scanViewController: SimpleScanViewController, creditCard: CreditCard) { 86 | if let topViewController = getTopViewController() { 87 | topViewController.dismiss(animated: true, completion: nil) 88 | } 89 | 90 | var resolvePayload: [String: Any] = [:] 91 | resolvePayload["action"] = "scanned" 92 | resolvePayload["payload"] = { 93 | var payload: [String: Any] = [:] 94 | payload["number"] = creditCard.number 95 | payload["cardholderName"] = creditCard.name 96 | payload["expiryMonth"] = creditCard.expiryMonth 97 | payload["expiryYear"] = creditCard.expiryYear 98 | return payload 99 | }() 100 | 101 | if let resolve = self.resolve { 102 | resolve(resolvePayload) 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /example/ios/example/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /example/App.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useCallback, useEffect } from 'react'; 2 | import { Text, SafeAreaView, TouchableOpacity, View } from 'react-native'; 3 | import Cardscan from 'react-native-cardscan'; 4 | import { CardView } from 'react-native-credit-card-input-view'; 5 | 6 | const StyledText = ({ color, bold, ...otherProps }) => ( 7 | 17 | ); 18 | 19 | if (Platform.OS === 'ios') { 20 | Cardscan.setiOSScanViewStyle({ 21 | 'backButtonTintColor': '#000', 22 | 'backButtonText': 'Cancel', 23 | 24 | 'backgroundColor': '#FFC0CB', 25 | 'backgroundColorOpacity': 0.5, 26 | 27 | 'cardDetailExpiryTextColor': '#FFF', 28 | 'cardDetailNameTextColor': '#FFF', 29 | 'cardDetailNumberTextColor': '#FFF', 30 | 31 | 'descriptionHeaderText': 'Scan Card', 32 | 'descriptionHeaderTextColor': '#FFF', 33 | 'descriptionHeaderTextFont': 'Avenir-Heavy', 34 | 'descriptionHeaderTextSize': 30.0, 35 | 36 | 'enableCameraPermissionText': "Enable your camera permissions", 37 | 'enableCameraPermissionTextColor': '#000', 38 | 'enableCameraPermissionTextFont': 'Avenir-LightOblique', 39 | 'enableCameraPermissionTextSize': 20.0, 40 | 41 | 'instructionText': 'Please center your card in the middle', 42 | 'instructionTextFont': 'Avenir-Light', 43 | 'instructionTextColor': '#00ff00', 44 | 'instructionTextSize': 20.0, 45 | 46 | 'roiBorderColor': '#ff0000', 47 | 'roiCornerRadius': 40.0, 48 | 49 | 'torchButtonTintColor': '#FFF', 50 | 'torchButtonPosition': 0, 51 | }); 52 | } 53 | 54 | export default () => { 55 | const [compatible, setCompatible] = useState(null); 56 | const [card, setCard] = useState(null); 57 | const [recentAction, setRecentAction] = useState('none'); 58 | 59 | const scanCard = useCallback(async () => { 60 | const { action, scanId, payload, canceledReason } = await Cardscan.scan(); 61 | setRecentAction(action); 62 | if (action === 'scanned') { 63 | var issuer = payload.issuer || '??'; 64 | if (issuer === 'MasterCard') { 65 | issuer = 'master-card'; 66 | } else if (issuer === 'American Express') { 67 | issuer = 'american-express'; 68 | } else { 69 | issuer = issuer.toLowerCase(); 70 | } 71 | setCard({ 72 | number: payload.number, 73 | expiryDay: payload.expiryDay || '', 74 | expiryMonth: payload.expiryMonth || '??', 75 | expiryYear: payload.expiryYear || '??', 76 | issuer: issuer, 77 | cvc: payload.cvc || '??', 78 | cardholderName: payload.cardholderName || '??', 79 | error: payload.error || '' 80 | }); 81 | } 82 | 83 | if (action === 'canceled') { 84 | if (canceledReason === 'enter_card_manually') { 85 | alert('Enter card manually'); 86 | } 87 | 88 | if (canceledReason === 'user_canceled') { 89 | alert('User canceled scan'); 90 | } 91 | 92 | if (canceledReason === 'camera_error') { 93 | alert('Camera error during scan'); 94 | } 95 | 96 | if (canceledReason === 'fatal_error') { 97 | alert('Processing error during scan'); 98 | } 99 | 100 | if (canceledReason === 'unknown') { 101 | alert('Unknown reason for scan cancellation'); 102 | } 103 | } 104 | }, [setCard, setRecentAction]); 105 | 106 | const checkCompatible = useCallback(async () => { 107 | const isCompatible = await Cardscan.isSupportedAsync(); 108 | setCompatible(isCompatible); 109 | }, [setCompatible]); 110 | 111 | useEffect(() => { 112 | checkCompatible(); 113 | }, []); 114 | 115 | return ( 116 | 117 | 118 | Supported:{' '} 119 | {compatible == null ? 'Loading...' : 120 | compatible ? 121 | Yes : 122 | No 123 | } 124 | 125 | {compatible && 126 | Recent action: {recentAction} 127 | } 128 | {compatible && 129 | 130 | Scan card 131 | 132 | } 133 | {card && 134 | 135 | 142 | 143 | } 144 | 145 | ); 146 | }; 147 | -------------------------------------------------------------------------------- /scripts/examples_postinstall.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* 4 | * Using libraries within examples and linking them within packages.json like: 5 | * "react-native-library-name": "file:../" 6 | * will cause problems with the metro bundler if the example will run via 7 | * `react-native run-[ios|android]`. This will result in an error as the metro 8 | * bundler will find multiple versions for the same module while resolving it. 9 | * The reason for that is that if the library is installed it also copies in the 10 | * example folder itself as well as the node_modules folder of the library 11 | * although their are defined in .npmignore and should be ignored in theory. 12 | * 13 | * This postinstall script removes the node_modules folder as well as all 14 | * entries from the libraries .npmignore file within the examples node_modules 15 | * folder after the library was installed. This should resolve the metro 16 | * bundler issue mentioned above. 17 | * 18 | * It is expected this scripts lives in the libraries root folder within a 19 | * scripts folder. As first parameter the relative path to the libraries 20 | * folder within the example's node_modules folder may be provided. 21 | * This script will determine the path from this project's package.json file 22 | * if no such relative path is provided. 23 | * An example's package.json entry could look like: 24 | * "postinstall": "node ../scripts/examples_postinstall.js node_modules/react-native-library-name/" 25 | */ 26 | 27 | 'use strict'; 28 | 29 | const fs = require('fs'); 30 | const path = require('path'); 31 | 32 | /// Delete all files and directories for the given path 33 | const removeFileDirectoryRecursively = fileDirPath => { 34 | // Remove file 35 | if (!fs.lstatSync(fileDirPath).isDirectory()) { 36 | fs.unlinkSync(fileDirPath); 37 | return; 38 | } 39 | 40 | // Go down the directory an remove each file / directory recursively 41 | fs.readdirSync(fileDirPath).forEach(entry => { 42 | const entryPath = path.join(fileDirPath, entry); 43 | removeFileDirectoryRecursively(entryPath); 44 | }); 45 | fs.rmdirSync(fileDirPath); 46 | }; 47 | 48 | /// Remove example/node_modules/react-native-library-name/node_modules directory 49 | const removeLibraryNodeModulesPath = (libraryNodeModulesPath) => { 50 | const nodeModulesPath = path.resolve(libraryNodeModulesPath, 'node_modules') 51 | 52 | if (!fs.existsSync(nodeModulesPath)) { 53 | console.log(`No node_modules path found at ${nodeModulesPath}. Skipping delete.`) 54 | return; 55 | } 56 | 57 | console.log(`Deleting: ${nodeModulesPath}`) 58 | try { 59 | removeFileDirectoryRecursively(nodeModulesPath); 60 | console.log(`Successfully deleted: ${nodeModulesPath}`) 61 | } catch (err) { 62 | console.log(`Error deleting ${nodeModulesPath}: ${err.message}`); 63 | } 64 | }; 65 | 66 | /// Remove all entries from the .npmignore within example/node_modules/react-native-library-name/ 67 | const removeLibraryNpmIgnorePaths = (npmIgnorePath, libraryNodeModulesPath) => { 68 | if (!fs.existsSync(npmIgnorePath)) { 69 | console.log(`No .npmignore path found at ${npmIgnorePath}. Skipping deleting content.`); 70 | return; 71 | } 72 | 73 | fs.readFileSync(npmIgnorePath, 'utf8').split(/\r?\n/).forEach(entry => { 74 | if (entry.length === 0) { 75 | return 76 | } 77 | 78 | const npmIgnoreLibraryNodeModulesEntryPath = path.resolve(libraryNodeModulesPath, entry); 79 | if (!fs.existsSync(npmIgnoreLibraryNodeModulesEntryPath)) { 80 | return; 81 | } 82 | 83 | console.log(`Deleting: ${npmIgnoreLibraryNodeModulesEntryPath}`) 84 | try { 85 | removeFileDirectoryRecursively(npmIgnoreLibraryNodeModulesEntryPath); 86 | console.log(`Successfully deleted: ${npmIgnoreLibraryNodeModulesEntryPath}`) 87 | } catch (err) { 88 | console.log(`Error deleting ${npmIgnoreLibraryNodeModulesEntryPath}: ${err.message}`); 89 | } 90 | }); 91 | }; 92 | 93 | // Main start sweeping process 94 | (() => { 95 | // Read out dir of example project 96 | const exampleDir = process.cwd(); 97 | 98 | console.log(`Starting postinstall cleanup for ${exampleDir}`); 99 | 100 | // Resolve the React Native library's path within the example's node_modules directory 101 | const libraryNodeModulesPath = process.argv.length > 2 102 | ? path.resolve(exampleDir, process.argv[2]) 103 | : path.resolve(exampleDir, 'node_modules', require('../package.json').name); 104 | 105 | console.log(`Removing unwanted artifacts for ${libraryNodeModulesPath}`); 106 | 107 | removeLibraryNodeModulesPath(libraryNodeModulesPath); 108 | 109 | const npmIgnorePath = path.resolve(__dirname, '../.npmignore'); 110 | removeLibraryNpmIgnorePaths(npmIgnorePath, libraryNodeModulesPath); 111 | })(); 112 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | finalize_release: 9 | name: Finalize Release 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: checkout 14 | uses: actions/checkout@v2 15 | with: 16 | ref: "master" 17 | token: ${{secrets.SERVICE_PERSONAL_ACCESS_TOKEN}} 18 | submodules: recursive 19 | 20 | - name: get current tag 21 | id: get_tag 22 | run: echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/} 23 | 24 | - name: update version 25 | env: 26 | TAG_VERSION: ${{ steps.get_tag.outputs.VERSION }} 27 | run: | 28 | sed -i -E 's/^ "version": "[^"]+",$/ "version": "'"$TAG_VERSION"'",/g' package.json 29 | cat package.json 30 | sed -i -E 's/^ "react-native-cardscan": "[^"]+",$/ "react-native-cardscan": "file:react-native-cardscan-'"$TAG_VERSION"'.tgz",/g' example/package.json 31 | cat example/package.json 32 | 33 | - name: update package lock 34 | run: | 35 | npm install 36 | 37 | - name: update example package lock 38 | run: | 39 | cd example 40 | npm pack .. 41 | npm update 42 | npm install 43 | cd .. 44 | 45 | - name: generate changelog 46 | uses: heinrichreimer/github-changelog-generator-action@v2.1.1 47 | with: 48 | user: "getbouncer" 49 | project: "react-native-cardscan" 50 | repo: "getbouncer/react-native-cardscan" 51 | token: ${{ secrets.SERVICE_PERSONAL_ACCESS_TOKEN }} 52 | pullRequests: "true" 53 | prWoLabels: "true" 54 | issues: "true" 55 | issuesWoLabels: "true" 56 | author: "true" 57 | base: "HISTORY.md" 58 | unreleased: "true" 59 | breakingLabels: "Versioning - BREAKING" 60 | enhancementLabels: "Type - Enhancement, Type - Feature" 61 | bugLabels: "Type - Fix, Bug - Fixed" 62 | deprecatedLabels: "Type - Deprecated" 63 | removedLabels: "Type - Removal" 64 | securityLabels: "Security Fix" 65 | excludeLabels: "Skip-Changelog" 66 | 67 | - name: create commit 68 | id: commit 69 | uses: stefanzweifel/git-auto-commit-action@v4 70 | with: 71 | commit_message: "Automatic changelog update" 72 | file_pattern: "package.json package-lock.json example/package.json CHANGELOG.md" 73 | 74 | 75 | android-lint: 76 | needs: finalize_release 77 | name: Android lint 78 | runs-on: ubuntu-latest 79 | 80 | steps: 81 | - name: checkout 82 | uses: actions/checkout@v2 83 | 84 | - name: set up JDK 1.8 85 | uses: actions/setup-java@v1 86 | with: 87 | java-version: 1.8 88 | 89 | - name: dependencies 90 | run: | 91 | npm install 92 | cd example 93 | npm install 94 | cd .. 95 | 96 | - name: lint 97 | run: | 98 | cd android 99 | ./gradlew lint 100 | cd .. 101 | 102 | - name: example-lint 103 | run: | 104 | cd example/android 105 | ./gradlew lint 106 | cd ../.. 107 | 108 | - name: upload-artifacts 109 | uses: actions/upload-artifact@v2 110 | if: failure() 111 | with: 112 | name: test-report 113 | path: ${{ github.workspace }}/*/build/reports/ 114 | 115 | android-unit-test: 116 | needs: finalize_release 117 | name: Android unit test 118 | runs-on: ubuntu-latest 119 | 120 | steps: 121 | - name: checkout 122 | uses: actions/checkout@v2 123 | 124 | - name: set up JDK 1.8 125 | uses: actions/setup-java@v1 126 | with: 127 | java-version: 1.8 128 | 129 | - name: dependencies 130 | run: | 131 | npm install 132 | cd example 133 | npm install 134 | cd .. 135 | 136 | - name: test 137 | run: | 138 | cd android 139 | ./gradlew test 140 | cd .. 141 | 142 | - name: example-test 143 | run: | 144 | cd example/android 145 | ./gradlew test 146 | cd ../.. 147 | 148 | - name: upload-artifacts 149 | uses: actions/upload-artifact@v2 150 | if: failure() 151 | with: 152 | name: test-report 153 | path: ${{ github.workspace }}/*/build/reports/ 154 | 155 | publish-npm: 156 | needs: [ android-lint, android-unit-test ] 157 | name: Publish to NPM 158 | runs-on: ubuntu-latest 159 | 160 | steps: 161 | - name: checkout 162 | uses: actions/checkout@v2 163 | with: 164 | ref: "master" 165 | 166 | - name: setup nodejs 167 | uses: actions/setup-node@v1 168 | with: 169 | node-version: '12' 170 | registry-url: 'https://registry.npmjs.org' 171 | 172 | - name: prepublish 173 | run: | 174 | npm install 175 | 176 | - name: publish to NPM 177 | run: | 178 | npm publish 179 | env: 180 | NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} 181 | -------------------------------------------------------------------------------- /example/ios/example.xcodeproj/xcshareddata/xcschemes/example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /example/ios/example.xcodeproj/xcshareddata/xcschemes/example-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | import groovy.json.JsonSlurper 2 | 3 | // android/build.gradle 4 | 5 | // based on: 6 | // 7 | // * https://github.com/facebook/react-native/blob/0.60-stable/template/android/build.gradle 8 | // original location: 9 | // - https://github.com/facebook/react-native/blob/0.58-stable/local-cli/templates/HelloWorld/android/build.gradle 10 | // 11 | // * https://github.com/facebook/react-native/blob/0.60-stable/template/android/app/build.gradle 12 | // original location: 13 | // - https://github.com/facebook/react-native/blob/0.58-stable/local-cli/templates/HelloWorld/android/app/build.gradle 14 | 15 | def DEFAULT_COMPILE_SDK_VERSION = 29 16 | def DEFAULT_BUILD_TOOLS_VERSION = '29.0.3' 17 | def DEFAULT_MIN_SDK_VERSION = 21 18 | def DEFAULT_TARGET_SDK_VERSION = 29 19 | 20 | def safeExtGet(prop, fallback) { 21 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 22 | } 23 | 24 | apply plugin: 'com.android.library' 25 | apply plugin: 'maven' 26 | 27 | buildscript { 28 | // The Android Gradle plugin is only required when opening the android folder stand-alone. 29 | // This avoids unnecessary downloads and potential conflicts when the library is included as a 30 | // module dependency in an application project. 31 | // ref: https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#sec:build_script_external_dependencies 32 | if (project == rootProject) { 33 | repositories { 34 | google() 35 | jcenter() 36 | } 37 | dependencies { 38 | classpath 'com.android.tools.build:gradle:4.0.2' 39 | } 40 | } 41 | } 42 | 43 | apply plugin: 'com.android.library' 44 | apply plugin: 'maven' 45 | 46 | android { 47 | compileSdkVersion safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION) 48 | buildToolsVersion safeExtGet('buildToolsVersion', DEFAULT_BUILD_TOOLS_VERSION) 49 | defaultConfig { 50 | minSdkVersion safeExtGet('minSdkVersion', DEFAULT_MIN_SDK_VERSION) 51 | targetSdkVersion safeExtGet('targetSdkVersion', DEFAULT_TARGET_SDK_VERSION) 52 | versionCode 1 53 | versionName "1.0" 54 | } 55 | lintOptions { 56 | abortOnError false 57 | } 58 | } 59 | 60 | repositories { 61 | // ref: https://www.baeldung.com/maven-local-repository 62 | mavenLocal() 63 | maven { 64 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 65 | url "$rootDir/../node_modules/react-native/android" 66 | } 67 | maven { 68 | // Android JSC is installed from npm 69 | url "$rootDir/../node_modules/jsc-android/dist" 70 | } 71 | google() 72 | jcenter() 73 | } 74 | 75 | dependencies { 76 | implementation 'androidx.appcompat:appcompat:1.2.0' 77 | //noinspection GradleDynamicVersion 78 | implementation 'com.facebook.react:react-native:+' // From node_modules 79 | implementation "com.getbouncer:cardscan-ui:2.0.0084" 80 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2" 81 | } 82 | 83 | def configureReactNativePom(def pom) { 84 | def packageJson = new JsonSlurper().parseText(file('../package.json').text) 85 | 86 | pom.project { 87 | name packageJson.title 88 | artifactId packageJson.name 89 | version = packageJson.version 90 | group = "com.getbouncer" 91 | description packageJson.description 92 | url packageJson.repository.baseUrl 93 | 94 | licenses { 95 | license { 96 | name packageJson.license 97 | url packageJson.repository.baseUrl + '/blob/master/' + packageJson.licenseFilename 98 | distribution 'repo' 99 | } 100 | } 101 | 102 | developers { 103 | developer { 104 | id packageJson.author.username 105 | name packageJson.author.name 106 | } 107 | } 108 | } 109 | } 110 | 111 | afterEvaluate { project -> 112 | // some Gradle build hooks ref: 113 | // https://www.oreilly.com/library/view/gradle-beyond-the/9781449373801/ch03.html 114 | task androidJavadoc(type: Javadoc) { 115 | source = android.sourceSets.main.java.srcDirs 116 | classpath += files(android.bootClasspath) 117 | classpath += files(project.getConfigurations().getByName('compile').asList()) 118 | include '**/*.java' 119 | } 120 | 121 | task androidJavadocJar(type: Jar, dependsOn: androidJavadoc) { 122 | classifier = 'javadoc' 123 | from androidJavadoc.destinationDir 124 | } 125 | 126 | task androidSourcesJar(type: Jar) { 127 | classifier = 'sources' 128 | from android.sourceSets.main.java.srcDirs 129 | include '**/*.java' 130 | } 131 | 132 | android.libraryVariants.all { variant -> 133 | def name = variant.name.capitalize() 134 | def javaCompileTask = variant.javaCompileProvider.get() 135 | 136 | task "jar${name}"(type: Jar, dependsOn: javaCompileTask) { 137 | from javaCompileTask.destinationDir 138 | } 139 | } 140 | 141 | artifacts { 142 | archives androidSourcesJar 143 | archives androidJavadocJar 144 | } 145 | 146 | task installArchives(type: Upload) { 147 | configuration = configurations.archives 148 | repositories.mavenDeployer { 149 | // Deploy to react-native-event-bridge/maven, ready to publish to npm 150 | repository url: "file://${projectDir}/../android/maven" 151 | configureReactNativePom pom 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deprecation Notice 2 | Hello from the Stripe (formerly Bouncer) team! 3 | 4 | We're excited to provide an update on the state and future of the [Card Scan OCR](https://github.com/stripe/stripe-android/tree/master/stripecardscan) product! As we continue to build into Stripe's ecosystem, we'll be supporting the mission to continuously improve the end customer experience in many of Stripe's core checkout products. 5 | 6 | If you are not currently a Stripe user, and interested in learning more about improving checkout experience through Stripe, please let us know and we can connect you with the team. 7 | 8 | If you are not currently a Stripe user, and want to continue using the existing SDK, you can do so free of charge. Starting January 1, 2022, we will no longer be charging for use of the existing Bouncer Card Scan OCR SDK. For product support on [Android](https://github.com/stripe/stripe-android/issues) and [iOS](https://github.com/stripe/stripe-ios/issues). For billing support, please email [bouncer-support@stripe.com](mailto:bouncer-support@stripe.com). 9 | 10 | For the new product, please visit the [stripe github repository](https://github.com/stripe/stripe-android/tree/master/stripecardscan). 11 | 12 | # CardScan 13 | This repository contains the legacy, deprecated open source code for [CardScan](https://www.getbouncer.com)'s react-native implementation. 14 | 15 | [CardScan](https://www.getbouncer.com/) is a relatively small library that provides fast and accurate payment card scanning. 16 | 17 | CardScan is the foundation for CardVerify enterprise libraries, which validate the authenticity of payment cards as they are scanned. 18 | 19 | ![Android Lint](https://github.com/getbouncer/react-native-cardscan/workflows/Android%20Lint/badge.svg) 20 | ![Android Unit Tests](https://github.com/getbouncer/react-native-cardscan/workflows/Android%20Unit%20Tests/badge.svg) 21 | ![Android Instrumentation Tests](https://github.com/getbouncer/react-native-cardscan/workflows/Android%20Instrumentation%20Tests/badge.svg) 22 | ![Release](https://github.com/getbouncer/react-native-cardscan/workflows/Release/badge.svg) 23 | [![GitHub release](https://img.shields.io/github/release/getbouncer/react-native-cardscan.svg?maxAge=60)](https://github.com/getbouncer/react-native-cardscan/releases) 24 | 25 | Native libraries for [android](https://github.com/getbouncer/cardscan-andorid) and [iOS](https://github.com/getbouncer/cardscan-ios) are also available in github. 26 | 27 | CardScan is open source, and available under a free-to-try license. See the [license](#license) section for details. 28 | 29 | ![demo](docs/images/demo.gif) 30 | 31 | ## Contents 32 | * [Requirements](#requirements) 33 | * [Demo](#demo) 34 | * [Integration](#integration) 35 | * [Customizing](#customizing) 36 | * [Developing](#developing) 37 | * [Troubleshooting](#troubleshooting) 38 | * [Authors](#authors) 39 | * [License](#license) 40 | 41 | ## Requirements 42 | * Android API level 21 or higher 43 | * iOS version 11 or higher 44 | 45 | ## Demo 46 | This repository contains a demonstration app for the CardScan product. To build and run the demo app, follow the instructions in the [example app documentation](https://docs.getbouncer.com/card-scan/react-native-integration-guide#example-app). 47 | 48 | ## Integration 49 | See the [integration documentation](https://docs.getbouncer.com/card-scan/react-native-integration-guide) in the Bouncer Docs. 50 | 51 | ### Provisioning an API key 52 | CardScan requires a valid API key to run. To provision an API key, visit the [Bouncer API console](https://api.getbouncer.com/console). 53 | 54 | ### Name and expiration extraction support (BETA) 55 | To test name and/or expiration extraction, please first provision an API key, then reach out to [support@getbouncer.com](mailto:support@getbouncer.com) with details about your use case and estimated volumes. 56 | 57 | Follow the [configuration guide](https://docs.getbouncer.com/card-scan/react-native-integration-guide#configuration) to enable name and expiry extraction support. 58 | 59 | ## Troubleshooting 60 | See the [troubleshooting page](https://docs.getbouncer.com/card-scan/react-native-integration-guide/troubleshooting) in the Bouncer Docs to check if we have covered common issues. 61 | 62 | ## Authors 63 | Adam Wushensky, Jaime Park, Sam King, and Zain ul Abi Din 64 | 65 | ## License 66 | This library is available under paid and free licenses. See the [LICENSE](LICENSE) file for the full license text. 67 | 68 | ### Quick summary 69 | In short, this library will remain free forever for non-commercial applications, but use by commercial applications is limited to 90 days, after which time a licensing agreement is required. We're also adding some legal liability protections. 70 | 71 | After this period commercial applications need to convert to a licensing agreement to continue to use this library. 72 | * Details of licensing (pricing, etc) are available at [https://getbouncer.com/pricing](https://getbouncer.com/pricing), or you can contact us at [license@getbouncer.com](mailto:license@getbouncer.com). 73 | 74 | ### More detailed summary 75 | What's allowed under the license: 76 | * Free use for any app for 90 days (for demos, evaluations, hackathons, etc). 77 | * Contributions (contributors must agree to the [Contributor License Agreement](Contributor%20License%20Agreement)) 78 | * Any modifications as needed to work in your app 79 | 80 | What's not allowed under the license: 81 | * Commercial applications using the license for longer than 90 days without a license agreement. 82 | * Using us now in a commercial app today? No worries! Just email [license@getbouncer.com](mailto:license@getbouncer.com) and we’ll get you set up. 83 | * Redistribution under a different license 84 | * Removing attribution 85 | * Modifying logos 86 | * Indemnification: using this free software is ‘at your own risk’, so you can’t sue Bouncer Technologies, Inc. for problems caused by this library 87 | 88 | Questions? Concerns? Please email us at [license@getbouncer.com](mailto:license@getbouncer.com) or ask us on [slack](https://getbouncer.slack.com). 89 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /example/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin, switch paths to Windows format before running java 129 | if $cygwin ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=$((i+1)) 158 | done 159 | case $i in 160 | (0) set -- ;; 161 | (1) set -- "$args0" ;; 162 | (2) set -- "$args0" "$args1" ;; 163 | (3) set -- "$args0" "$args1" "$args2" ;; 164 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=$(save "$@") 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 184 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 185 | cd "$(dirname "$0")" 186 | fi 187 | 188 | exec "$JAVACMD" "$@" 189 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | 3 | import com.android.build.OutputFile 4 | 5 | /** 6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets 7 | * and bundleReleaseJsAndAssets). 8 | * These basically call `react-native bundle` with the correct arguments during the Android build 9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 10 | * bundle directly from the development server. Below you can see all the possible configurations 11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the 12 | * `apply from: "../../node_modules/react-native/react.gradle"` line. 13 | * 14 | * project.ext.react = [ 15 | * // the name of the generated asset file containing your JS bundle 16 | * bundleAssetName: "index.android.bundle", 17 | * 18 | * // the entry file for bundle generation 19 | * entryFile: "index.android.js", 20 | * 21 | * // whether to bundle JS and assets in debug mode 22 | * bundleInDebug: false, 23 | * 24 | * // whether to bundle JS and assets in release mode 25 | * bundleInRelease: true, 26 | * 27 | * // whether to bundle JS and assets in another build variant (if configured). 28 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 29 | * // The configuration property can be in the following formats 30 | * // 'bundleIn${productFlavor}${buildType}' 31 | * // 'bundleIn${buildType}' 32 | * // bundleInFreeDebug: true, 33 | * // bundleInPaidRelease: true, 34 | * // bundleInBeta: true, 35 | * 36 | * // whether to disable dev mode in custom build variants (by default only disabled in release) 37 | * // for example: to disable dev mode in the staging build type (if configured) 38 | * devDisabledInStaging: true, 39 | * // The configuration property can be in the following formats 40 | * // 'devDisabledIn${productFlavor}${buildType}' 41 | * // 'devDisabledIn${buildType}' 42 | * 43 | * // the root of your project, i.e. where "package.json" lives 44 | * root: "../../", 45 | * 46 | * // where to put the JS bundle asset in debug mode 47 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 48 | * 49 | * // where to put the JS bundle asset in release mode 50 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 51 | * 52 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 53 | * // require('./image.png')), in debug mode 54 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 55 | * 56 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 57 | * // require('./image.png')), in release mode 58 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 59 | * 60 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 61 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 62 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 63 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 64 | * // for example, you might want to remove it from here. 65 | * inputExcludes: ["android/**", "ios/**"], 66 | * 67 | * // override which node gets called and with what additional arguments 68 | * nodeExecutableAndArgs: ["node"], 69 | * 70 | * // supply additional arguments to the packager 71 | * extraPackagerArgs: [] 72 | * ] 73 | */ 74 | 75 | project.ext.react = [ 76 | entryFile: "index.js" 77 | ] 78 | 79 | apply from: "../../node_modules/react-native/react.gradle" 80 | 81 | /** 82 | * Set this to true to create two separate APKs instead of one: 83 | * - An APK that only works on ARM devices 84 | * - An APK that only works on x86 devices 85 | * The advantage is the size of the APK is reduced by about 4MB. 86 | * Upload all the APKs to the Play Store and people will download 87 | * the correct one based on the CPU architecture of their device. 88 | */ 89 | def enableSeparateBuildPerCPUArchitecture = false 90 | 91 | /** 92 | * Run Proguard to shrink the Java bytecode in release builds. 93 | */ 94 | def enableProguardInReleaseBuilds = false 95 | 96 | android { 97 | compileSdkVersion rootProject.ext.compileSdkVersion 98 | 99 | compileOptions { 100 | sourceCompatibility JavaVersion.VERSION_1_8 101 | targetCompatibility JavaVersion.VERSION_1_8 102 | } 103 | 104 | defaultConfig { 105 | applicationId "com.getbouncer.example" 106 | minSdkVersion rootProject.ext.minSdkVersion 107 | targetSdkVersion rootProject.ext.targetSdkVersion 108 | versionCode 1 109 | versionName "1.0" 110 | } 111 | splits { 112 | abi { 113 | reset() 114 | enable enableSeparateBuildPerCPUArchitecture 115 | universalApk false // If true, also generate a universal APK 116 | include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" 117 | } 118 | } 119 | buildTypes { 120 | release { 121 | minifyEnabled enableProguardInReleaseBuilds 122 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 123 | } 124 | } 125 | // applicationVariants are e.g. debug, release 126 | applicationVariants.all { variant -> 127 | variant.outputs.each { output -> 128 | // For each separate APK per architecture, set a unique version code as described here: 129 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits 130 | def versionCodes = ["armeabi-v7a":1, "x86":2, "arm64-v8a": 3, "x86_64": 4] 131 | def abi = output.getFilter(OutputFile.ABI) 132 | if (abi != null) { // null for the universal-debug, universal-release variants 133 | output.versionCodeOverride = 134 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 135 | } 136 | } 137 | } 138 | aaptOptions { 139 | noCompress "tflite" 140 | } 141 | } 142 | 143 | project.ext.react = [ 144 | entryFile: "index.js" , 145 | enableHermes: false 146 | ] 147 | 148 | def jscFlavor = 'org.webkit:android-jsc:+' 149 | def enableHermes = project.ext.react.get("enableHermes", false); 150 | 151 | dependencies { 152 | implementation project(':react-native-cardscan') 153 | implementation fileTree(dir: "libs", include: ["*.jar"]) 154 | implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}" 155 | implementation "com.facebook.react:react-native:+" // From node_modules 156 | implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" 157 | 158 | implementation "com.getbouncer:cardscan-ui:2.0.0084" 159 | implementation "com.getbouncer:scan-payment-card-detect:2.0.0084" 160 | implementation "com.getbouncer:scan-payment-ocr:2.0.0084" 161 | implementation "com.getbouncer:tensorflow-lite:2.0.0084" 162 | implementation "com.getbouncer:scan-camerax:2.0.0084" 163 | 164 | if (enableHermes) { 165 | def hermesPath = "../../node_modules/hermesvm/android/"; 166 | debugImplementation files(hermesPath + "hermes-debug.aar") 167 | releaseImplementation files(hermesPath + "hermes-release.aar") 168 | } else { 169 | implementation jscFlavor 170 | } 171 | } 172 | 173 | // Run this once to be able to run the application with BUCK 174 | // puts all compile dependencies into folder libs for BUCK to use 175 | task copyDownloadableDepsToLibs(type: Copy) { 176 | from configurations.compile 177 | into 'libs' 178 | } 179 | -------------------------------------------------------------------------------- /android/src/main/java/com/getbouncer/RNCardscanModule.java: -------------------------------------------------------------------------------- 1 | package com.getbouncer; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.annotation.Nullable; 8 | 9 | import com.facebook.react.bridge.ActivityEventListener; 10 | import com.facebook.react.bridge.Promise; 11 | import com.facebook.react.bridge.ReactApplicationContext; 12 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 13 | import com.facebook.react.bridge.ReactMethod; 14 | import com.facebook.react.bridge.WritableMap; 15 | import com.facebook.react.bridge.WritableNativeMap; 16 | import com.getbouncer.cardscan.ui.CardScanActivity; 17 | import com.getbouncer.cardscan.ui.CardScanActivityResult; 18 | import com.getbouncer.cardscan.ui.CardScanActivityResultHandler; 19 | 20 | public class RNCardscanModule extends ReactContextBaseJavaModule { 21 | private static final int SCAN_REQUEST_CODE = 51234; 22 | 23 | public static String apiKey = null; 24 | public static boolean enableExpiryExtraction = false; 25 | public static boolean enableNameExtraction = false; 26 | public static boolean enableEnterCardManually = false; 27 | 28 | private final ReactApplicationContext reactContext; 29 | 30 | private Promise scanPromise; 31 | 32 | @Override 33 | public void initialize() { 34 | CardScanActivity.warmUp(this.reactContext.getApplicationContext(), apiKey, true); 35 | } 36 | 37 | public RNCardscanModule(ReactApplicationContext reactContext) { 38 | super(reactContext); 39 | this.reactContext = reactContext; 40 | this.reactContext.addActivityEventListener(new ActivityEventListener() { 41 | 42 | @Override 43 | public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { 44 | if (requestCode == SCAN_REQUEST_CODE) { 45 | CardScanActivity.parseScanResult(resultCode, data, new CardScanActivityResultHandler() { 46 | @Override 47 | public void cardScanned( 48 | @Nullable String scanId, 49 | @NonNull CardScanActivityResult cardScanActivityResult 50 | ) { 51 | 52 | final WritableMap cardMap = new WritableNativeMap(); 53 | cardMap.putString("number", cardScanActivityResult.getPan()); 54 | cardMap.putString("expiryDay", cardScanActivityResult.getExpiryDay()); 55 | cardMap.putString("expiryMonth", cardScanActivityResult.getExpiryMonth()); 56 | cardMap.putString("expiryYear", cardScanActivityResult.getExpiryYear()); 57 | cardMap.putString("issuer", cardScanActivityResult.getNetworkName()); 58 | cardMap.putString("cvc", cardScanActivityResult.getCvc()); 59 | cardMap.putString("cardholderName", cardScanActivityResult.getCardholderName()); 60 | cardMap.putString("error", cardScanActivityResult.getErrorString()); 61 | 62 | final WritableMap map = new WritableNativeMap(); 63 | map.putString("action", "scanned"); 64 | map.putMap("payload", cardMap); 65 | map.putString("scanId", scanId); 66 | 67 | if (scanPromise != null) { 68 | scanPromise.resolve(map); 69 | scanPromise = null; 70 | } 71 | } 72 | 73 | @Override 74 | public void enterManually(String scanId) { 75 | final WritableMap map = new WritableNativeMap(); 76 | map.putString("action", "canceled"); 77 | map.putString("canceledReason", "enter_card_manually"); 78 | map.putString("scanId", scanId); 79 | 80 | if (scanPromise != null) { 81 | scanPromise.resolve(map); 82 | scanPromise = null; 83 | } 84 | } 85 | 86 | @Override 87 | public void userCanceled(String scanId) { 88 | final WritableMap map = new WritableNativeMap(); 89 | map.putString("action", "canceled"); 90 | map.putString("canceledReason", "user_canceled"); 91 | map.putString("scanId", scanId); 92 | 93 | if (scanPromise != null) { 94 | scanPromise.resolve(map); 95 | scanPromise = null; 96 | } 97 | } 98 | 99 | @Override 100 | public void cameraError(String scanId) { 101 | final WritableMap map = new WritableNativeMap(); 102 | map.putString("action", "canceled"); 103 | map.putString("canceledReason", "camera_error"); 104 | map.putString("scanId", scanId); 105 | 106 | if (scanPromise != null) { 107 | scanPromise.resolve(map); 108 | scanPromise = null; 109 | } 110 | } 111 | 112 | @Override 113 | public void analyzerFailure(String scanId) { 114 | final WritableMap map = new WritableNativeMap(); 115 | map.putString("action", "canceled"); 116 | map.putString("canceledReason", "fatal_error"); 117 | map.putString("scanId", scanId); 118 | 119 | if (scanPromise != null) { 120 | scanPromise.resolve(map); 121 | scanPromise = null; 122 | } 123 | } 124 | 125 | @Override 126 | public void canceledUnknown(String scanId) { 127 | final WritableMap map = new WritableNativeMap(); 128 | map.putString("action", "canceled"); 129 | map.putString("canceledReason", "unknown"); 130 | map.putString("scanId", scanId); 131 | 132 | if (scanPromise != null) { 133 | scanPromise.resolve(map); 134 | scanPromise = null; 135 | } 136 | } 137 | }); 138 | } 139 | } 140 | 141 | @Override 142 | public void onNewIntent(Intent intent) { } 143 | }); 144 | } 145 | 146 | @Override 147 | @NonNull 148 | public String getName() { 149 | return "RNCardscan"; 150 | } 151 | 152 | @ReactMethod 153 | public void isSupportedAsync(Promise promise) { 154 | promise.resolve(true); 155 | } 156 | 157 | @ReactMethod 158 | public void scan(Promise promise) { 159 | scanPromise = promise; 160 | 161 | final Intent intent = CardScanActivity.buildIntent( 162 | /* context */ this.reactContext.getApplicationContext(), 163 | /* apiKey */ apiKey, 164 | /* enableEnterCardManually */ enableEnterCardManually, 165 | /* enableExpiryExtraction */ enableExpiryExtraction, 166 | /* enableNameExtraction */ enableNameExtraction 167 | ); 168 | this.reactContext.startActivityForResult(intent, SCAN_REQUEST_CODE, null); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /ios/RNCardScanViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RNCardScanViewController.swift 3 | // RNCardScan 4 | // 5 | // Created by Jaime Park on 9/23/21. 6 | // Copyright © 2021 Facebook. All rights reserved. 7 | // 8 | 9 | import CardScan 10 | import Foundation 11 | import UIKit 12 | 13 | // MARK: Custom Scan 14 | @available(iOS 11.2, *) 15 | class RNCardScanViewController: SimpleScanViewController { 16 | var scanStyle = RNCardScanStyle() 17 | lazy var instructionLabel = UILabel() 18 | 19 | init(viewStyle: NSDictionary?) { 20 | super.init(nibName: nil, bundle: nil) 21 | handleScanStyleDictionary(viewStyle: viewStyle) 22 | } 23 | 24 | @objc required dynamic init?(coder: NSCoder) { 25 | fatalError("init(coder:) has not been implemented") 26 | } 27 | 28 | override func viewDidLoad() { 29 | super.viewDidLoad() 30 | } 31 | 32 | func handleScanStyleDictionary(viewStyle: NSDictionary?) { 33 | guard let dict = viewStyle, 34 | let data = try? JSONSerialization.data(withJSONObject: dict, options: []), 35 | let decodedScanStyle = try? JSONDecoder().decode(RNCardScanStyle.self, from: data) else { 36 | return 37 | } 38 | 39 | self.scanStyle = decodedScanStyle 40 | } 41 | 42 | override func setupUiComponents() { 43 | super.setupUiComponents() 44 | setupInstructionUI() 45 | } 46 | 47 | override func setupConstraints() { 48 | super.setupConstraints() 49 | 50 | // only turn on these constraints if we have instructions to show 51 | if let _ = scanStyle.instructionText { 52 | instructionLabel.translatesAutoresizingMaskIntoConstraints = false 53 | instructionLabel.centerXAnchor.constraint(equalTo: roiView.centerXAnchor, constant: 0).isActive = true 54 | instructionLabel.topAnchor.constraint(equalTo: roiView.bottomAnchor, constant: 15).isActive = true 55 | instructionLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16).isActive = true 56 | instructionLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16).isActive = true 57 | } 58 | } 59 | 60 | // MARK: -- Instruction UI -- 61 | func setupInstructionUI() { 62 | if let instructionText = scanStyle.instructionText { 63 | instructionLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 300, height: 75)) 64 | instructionLabel.text = instructionText 65 | instructionLabel.textAlignment = .center 66 | instructionLabel.numberOfLines = 2 67 | instructionLabel.textColor = .white 68 | 69 | if let instructionTextColor = scanStyle.instructionTextColor { 70 | instructionLabel.textColor = UIColor(hexString: instructionTextColor) 71 | } 72 | 73 | if let intructionTextFont = scanStyle.instructionTextFont { 74 | instructionLabel.font = UIFont(name: intructionTextFont, size: 15) 75 | } 76 | 77 | if let instructionTextSize = scanStyle.instructionTextSize { 78 | instructionLabel.font = instructionLabel.font.withSize(instructionTextSize) 79 | } 80 | 81 | self.view.addSubview(instructionLabel) 82 | } 83 | } 84 | 85 | //MARK: -- Background UI -- 86 | override public func setupBlurViewUi() { 87 | super.setupBlurViewUi() 88 | 89 | if let backgroundColor = scanStyle.backgroundColor { 90 | blurView.backgroundColor = UIColor(hexString: backgroundColor).withAlphaComponent(scanStyle.backgroundColorOpacity ?? 0.5) 91 | } 92 | } 93 | 94 | // MARK: -- ROI UI -- 95 | override public func setupRoiViewUi() { 96 | super.setupRoiViewUi() 97 | if let roiCornerRadius = scanStyle.roiCornerRadius { 98 | regionOfInterestCornerRadius = roiCornerRadius 99 | } 100 | 101 | if let roiBorderColor = scanStyle.roiBorderColor { 102 | roiView.layer.borderColor = UIColor(hexString: roiBorderColor).cgColor 103 | } 104 | } 105 | 106 | // MARK: -- Description UI -- 107 | override public func setupDescriptionTextUi() { 108 | super.setupDescriptionTextUi() 109 | 110 | if let descriptionHeaderText = scanStyle.descriptionHeaderText { 111 | descriptionText.text = descriptionHeaderText 112 | } 113 | 114 | if let descriptionTextColor = scanStyle.descriptionHeaderTextColor { 115 | descriptionText.textColor = UIColor(hexString: descriptionTextColor) 116 | } 117 | 118 | if let descriptionTextFont = scanStyle.descriptionHeaderTextFont { 119 | descriptionText.font = UIFont(name: descriptionTextFont, size: 30) 120 | } 121 | 122 | if let descriptionTextSize = scanStyle.descriptionHeaderTextSize { 123 | descriptionText.font = descriptionText.font.withSize(descriptionTextSize) 124 | } 125 | } 126 | 127 | // MARK: -- Close UI -- 128 | override public func setupCloseButtonUi() { 129 | super.setupCloseButtonUi() 130 | if let backButtonText = scanStyle.backButtonText { 131 | closeButton.setTitle(backButtonText, for: .normal) 132 | } else if let backArrowImage = UIImage(named: "bouncer_scan_back") { 133 | closeButton.setTitle(scanStyle.backButtonText ?? "", for: .normal) 134 | closeButton.setImage(backArrowImage, for: .normal) 135 | } 136 | 137 | if let backButtonTintColor = scanStyle.backButtonTintColor { 138 | closeButton.tintColor = UIColor(hexString: backButtonTintColor) 139 | } 140 | } 141 | 142 | // MARK: -- Torch UI -- 143 | override public func setupTorchButtonUi() { 144 | super.setupTorchButtonUi() 145 | if let torchButtonText = scanStyle.torchButtonText { 146 | torchButton.setTitle(torchButtonText, for: .normal) 147 | } else if let torchImage = UIImage(named: "bouncer_scan_flash_on") { 148 | torchButton.setTitle(scanStyle.torchButtonText ?? "", for: .normal) 149 | torchButton.setImage(torchImage, for: .normal) 150 | } 151 | 152 | if let torchButtonTintColor = scanStyle.torchButtonTintColor { 153 | torchButton.tintColor = UIColor(hexString: torchButtonTintColor) 154 | } 155 | } 156 | 157 | override public func setupTorchButtonConstraints() { 158 | let torchButtonPosition = TorchPosition(rawValue: scanStyle.torchButtonPosition ?? 0) 159 | let margins = view.layoutMarginsGuide 160 | 161 | let topRightConstraints = [ 162 | torchButton.topAnchor.constraint(equalTo: margins.topAnchor, constant: 16.0), 163 | torchButton.trailingAnchor.constraint(equalTo: margins.trailingAnchor) 164 | ] 165 | 166 | let bottomConstraints = [ 167 | torchButton.bottomAnchor.constraint(equalTo: margins.bottomAnchor, constant: -50.0), 168 | torchButton.centerXAnchor.constraint(equalTo: margins.centerXAnchor, constant: 0.0) 169 | ] 170 | 171 | switch torchButtonPosition { 172 | case .topRight: 173 | NSLayoutConstraint.activate(topRightConstraints) 174 | case .bottom: 175 | NSLayoutConstraint.activate(bottomConstraints) 176 | case .none: 177 | NSLayoutConstraint.activate(topRightConstraints) 178 | } 179 | } 180 | 181 | override func torchButtonPress() { 182 | super.torchButtonPress() 183 | 184 | if isTorchOn() { 185 | torchButton.setImage(UIImage(named: "bouncer_scan_flash_off"), for: .normal) 186 | } else { 187 | torchButton.setImage(UIImage(named: "bouncer_scan_flash_on"), for: .normal) 188 | } 189 | } 190 | 191 | // MARK: -- Permissions UI -- 192 | override public func setupDenyUi() { 193 | super.setupDenyUi() 194 | 195 | let text = scanStyle.enableCameraPermissionText ?? RNCardScanViewController.enableCameraPermissionString 196 | let attributedString = NSMutableAttributedString(string: text) 197 | enableCameraPermissionsText.text = text 198 | 199 | let textColor = UIColor(hexString: scanStyle.enableCameraPermissionTextColor ?? "#FFFFFF") 200 | attributedString.addAttribute(NSAttributedString.Key.underlineColor, value: textColor, range: NSRange(location: 0, length: text.count)) 201 | attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: textColor, range: NSRange(location: 0, length: text.count)) 202 | attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: NSRange(location: 0, length: text.count)) 203 | enableCameraPermissionsText.textColor = textColor 204 | 205 | var font: UIFont? = UIFont.systemFont(ofSize: 20) 206 | 207 | if let enableCameraPermissionFont = scanStyle.enableCameraPermissionTextFont { 208 | font = UIFont(name: enableCameraPermissionFont, size: 20) 209 | } 210 | 211 | if let fontSize = scanStyle.enableCameraPermissionTextSize { 212 | font = font?.withSize(fontSize) 213 | } 214 | 215 | attributedString.addAttribute(NSAttributedString.Key.font, value: font, range: NSRange(location: 0, length: text.count)) 216 | enableCameraPermissionsButton.setAttributedTitle(attributedString, for: .normal) 217 | enableCameraPermissionsText.textAlignment = .center 218 | } 219 | 220 | //MARK: -- Card Detail UI -- 221 | override public func setupCardDetailsUi() { 222 | super.setupCardDetailsUi() 223 | 224 | if let numberColor = scanStyle.cardDetailNumberTextColor { 225 | numberText.textColor = UIColor(hexString: numberColor) 226 | } 227 | 228 | if let nameColor = scanStyle.cardDetailNameTextColor { 229 | nameText.textColor = UIColor(hexString: nameColor) 230 | } 231 | 232 | if let expiryColor = scanStyle.cardDetailExpiryTextColor { 233 | expiryText.textColor = UIColor(hexString: expiryColor) 234 | } 235 | } 236 | } 237 | 238 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [2.0.0](https://github.com/getbouncer/react-native-cardscan/tree/2.0.0) (2021-10-04) 4 | 5 | **Closed issues:** 6 | 7 | - Getting version error during pod install [\#153](https://github.com/getbouncer/react-native-cardscan/issues/153) 8 | - Value of card expiry month, year [\#150](https://github.com/getbouncer/react-native-cardscan/issues/150) 9 | - Trying to install package in react native causes build failure [\#129](https://github.com/getbouncer/react-native-cardscan/issues/129) 10 | - \[Customizing\] How to customize the câmera overlay? [\#120](https://github.com/getbouncer/react-native-cardscan/issues/120) 11 | - Credit Card Image [\#116](https://github.com/getbouncer/react-native-cardscan/issues/116) 12 | - iOS: not building project issue \(ld: symbol\(s\) not found for architecture arm64\) [\#100](https://github.com/getbouncer/react-native-cardscan/issues/100) 13 | - \> Task :react-native-cardscan:packageDebugAssets FAILED [\#95](https://github.com/getbouncer/react-native-cardscan/issues/95) 14 | - iOS Build Issue [\#56](https://github.com/getbouncer/react-native-cardscan/issues/56) 15 | 16 | **Merged pull requests:** 17 | 18 | - Release 2.0.0 [\#155](https://github.com/getbouncer/react-native-cardscan/pull/155) ([jaimepark-stripe](https://github.com/jaimepark-stripe)) 19 | - Create RN UI Customization interface [\#152](https://github.com/getbouncer/react-native-cardscan/pull/152) ([jaimepark-stripe](https://github.com/jaimepark-stripe)) 20 | - Update react dependency from React to React-Core [\#149](https://github.com/getbouncer/react-native-cardscan/pull/149) ([kingst-stripe](https://github.com/kingst-stripe)) 21 | - Clean up the example app [\#148](https://github.com/getbouncer/react-native-cardscan/pull/148) ([kingst-stripe](https://github.com/kingst-stripe)) 22 | - Update CODEOWNERS [\#146](https://github.com/getbouncer/react-native-cardscan/pull/146) ([jaimepark-stripe](https://github.com/jaimepark-stripe)) 23 | 24 | ## [1.1.30](https://github.com/getbouncer/react-native-cardscan/tree/1.1.30) (2021-04-22) 25 | 26 | ## [1.1.29](https://github.com/getbouncer/react-native-cardscan/tree/1.1.29) (2021-04-16) 27 | 28 | **Closed issues:** 29 | 30 | - Is it possible to scan cardholderName on android? [\#106](https://github.com/getbouncer/react-native-cardscan/issues/106) 31 | 32 | **Merged pull requests:** 33 | 34 | - Update android version [\#115](https://github.com/getbouncer/react-native-cardscan/pull/115) ([awushensky](https://github.com/awushensky)) 35 | - Bump to CardScan 2.0.9 [\#103](https://github.com/getbouncer/react-native-cardscan/pull/103) ([jaimejiyepark](https://github.com/jaimejiyepark)) 36 | 37 | ## [1.1.28](https://github.com/getbouncer/react-native-cardscan/tree/1.1.28) (2021-03-10) 38 | 39 | **Closed issues:** 40 | 41 | - CVC number not scanned [\#84](https://github.com/getbouncer/react-native-cardscan/issues/84) 42 | 43 | **Merged pull requests:** 44 | 45 | - Upgrade android version [\#117](https://github.com/getbouncer/react-native-cardscan/pull/117) ([awushensky](https://github.com/awushensky)) 46 | 47 | ## [1.1.26](https://github.com/getbouncer/react-native-cardscan/tree/1.1.26) (2020-12-04) 48 | 49 | **Merged pull requests:** 50 | 51 | - Upgrade native libraries [\#83](https://github.com/getbouncer/react-native-cardscan/pull/83) ([awushensky](https://github.com/awushensky)) 52 | - Update native libraries [\#72](https://github.com/getbouncer/react-native-cardscan/pull/72) ([awushensky](https://github.com/awushensky)) 53 | - Fix NPE [\#70](https://github.com/getbouncer/react-native-cardscan/pull/70) ([awushensky](https://github.com/awushensky)) 54 | - Upgrade android [\#69](https://github.com/getbouncer/react-native-cardscan/pull/69) ([awushensky](https://github.com/awushensky)) 55 | - Upgrade cardscan [\#67](https://github.com/getbouncer/react-native-cardscan/pull/67) ([awushensky](https://github.com/awushensky)) 56 | - Upgrade native cardscan [\#65](https://github.com/getbouncer/react-native-cardscan/pull/65) ([awushensky](https://github.com/awushensky)) 57 | - Upgrade cardscan [\#64](https://github.com/getbouncer/react-native-cardscan/pull/64) ([awushensky](https://github.com/awushensky)) 58 | 59 | ## [1.1.16](https://github.com/getbouncer/react-native-cardscan/tree/1.1.16) (2020-10-06) 60 | 61 | **Merged pull requests:** 62 | 63 | - Upgrade android [\#62](https://github.com/getbouncer/react-native-cardscan/pull/62) ([awushensky](https://github.com/awushensky)) 64 | 65 | ## [1.1.15](https://github.com/getbouncer/react-native-cardscan/tree/1.1.15) (2020-10-05) 66 | 67 | **Merged pull requests:** 68 | 69 | - Pin cardscan version [\#61](https://github.com/getbouncer/react-native-cardscan/pull/61) ([awushensky](https://github.com/awushensky)) 70 | - Update README.md [\#60](https://github.com/getbouncer/react-native-cardscan/pull/60) ([jaimejiyepark](https://github.com/jaimejiyepark)) 71 | 72 | ## [1.1.14](https://github.com/getbouncer/react-native-cardscan/tree/1.1.14) (2020-10-02) 73 | 74 | **Merged pull requests:** 75 | 76 | - Update android version [\#59](https://github.com/getbouncer/react-native-cardscan/pull/59) ([awushensky](https://github.com/awushensky)) 77 | 78 | ## [1.1.12](https://github.com/getbouncer/react-native-cardscan/tree/1.1.12) (2020-10-02) 79 | 80 | **Merged pull requests:** 81 | 82 | - Update android version [\#58](https://github.com/getbouncer/react-native-cardscan/pull/58) ([awushensky](https://github.com/awushensky)) 83 | 84 | ## [1.1.11](https://github.com/getbouncer/react-native-cardscan/tree/1.1.11) (2020-09-23) 85 | 86 | **Merged pull requests:** 87 | 88 | - Bump cardscan version [\#52](https://github.com/getbouncer/react-native-cardscan/pull/52) ([awushensky](https://github.com/awushensky)) 89 | - Fix dismiss view [\#51](https://github.com/getbouncer/react-native-cardscan/pull/51) ([jaimejiyepark](https://github.com/jaimejiyepark)) 90 | 91 | ## [1.1.10](https://github.com/getbouncer/react-native-cardscan/tree/1.1.10) (2020-09-18) 92 | 93 | **Merged pull requests:** 94 | 95 | - Fix package lock [\#50](https://github.com/getbouncer/react-native-cardscan/pull/50) ([awushensky](https://github.com/awushensky)) 96 | - Upgrade android [\#49](https://github.com/getbouncer/react-native-cardscan/pull/49) ([awushensky](https://github.com/awushensky)) 97 | - Fix for presenting scan view [\#48](https://github.com/getbouncer/react-native-cardscan/pull/48) ([jaimejiyepark](https://github.com/jaimejiyepark)) 98 | 99 | ## [1.1.9](https://github.com/getbouncer/react-native-cardscan/tree/1.1.9) (2020-09-15) 100 | 101 | **Merged pull requests:** 102 | 103 | - Upgrade android version [\#47](https://github.com/getbouncer/react-native-cardscan/pull/47) ([awushensky](https://github.com/awushensky)) 104 | 105 | ## [1.1.7](https://github.com/getbouncer/react-native-cardscan/tree/1.1.7) (2020-09-03) 106 | 107 | **Merged pull requests:** 108 | 109 | - Update android version [\#44](https://github.com/getbouncer/react-native-cardscan/pull/44) ([awushensky](https://github.com/awushensky)) 110 | - Update iOS [\#43](https://github.com/getbouncer/react-native-cardscan/pull/43) ([awushensky](https://github.com/awushensky)) 111 | - Upgrade dependencies [\#42](https://github.com/getbouncer/react-native-cardscan/pull/42) ([awushensky](https://github.com/awushensky)) 112 | - Bump react-native from 0.62.2 to 0.63.2 [\#32](https://github.com/getbouncer/react-native-cardscan/pull/32) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 113 | - Bump cardscan-ui from 2.0.0014 to 2.0.0016 in /android [\#28](https://github.com/getbouncer/react-native-cardscan/pull/28) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 114 | - Bump kotlinx-coroutines-core from 1.3.7 to 1.3.8 in /android [\#27](https://github.com/getbouncer/react-native-cardscan/pull/27) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 115 | - \[Security\] Bump lodash from 4.17.15 to 4.17.19 [\#26](https://github.com/getbouncer/react-native-cardscan/pull/26) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 116 | - Bump cardscan-ui from 2.0.0013 to 2.0.0014 in /android [\#25](https://github.com/getbouncer/react-native-cardscan/pull/25) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 117 | - Bump gradle from 4.0.0 to 4.0.1 in /android [\#24](https://github.com/getbouncer/react-native-cardscan/pull/24) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 118 | - Update cardscan [\#23](https://github.com/getbouncer/react-native-cardscan/pull/23) ([jaimejiyepark](https://github.com/jaimejiyepark)) 119 | - Support expiry extraction [\#22](https://github.com/getbouncer/react-native-cardscan/pull/22) ([awushensky](https://github.com/awushensky)) 120 | - Support name extraction [\#20](https://github.com/getbouncer/react-native-cardscan/pull/20) ([awushensky](https://github.com/awushensky)) 121 | 122 | ## [1.1.4](https://github.com/getbouncer/react-native-cardscan/tree/1.1.4) (2020-06-25) 123 | 124 | **Closed issues:** 125 | 126 | - react-native issue [\#13](https://github.com/getbouncer/react-native-cardscan/issues/13) 127 | 128 | **Merged pull requests:** 129 | 130 | - Upgrade android to 2.0 [\#16](https://github.com/getbouncer/react-native-cardscan/pull/16) ([awushensky](https://github.com/awushensky)) 131 | - Fix readme [\#14](https://github.com/getbouncer/react-native-cardscan/pull/14) ([awushensky](https://github.com/awushensky)) 132 | - Update example [\#12](https://github.com/getbouncer/react-native-cardscan/pull/12) ([awushensky](https://github.com/awushensky)) 133 | - Upgrade react native [\#11](https://github.com/getbouncer/react-native-cardscan/pull/11) ([awushensky](https://github.com/awushensky)) 134 | - Upgrade react-native [\#10](https://github.com/getbouncer/react-native-cardscan/pull/10) ([awushensky](https://github.com/awushensky)) 135 | - More cleanup [\#9](https://github.com/getbouncer/react-native-cardscan/pull/9) ([awushensky](https://github.com/awushensky)) 136 | 137 | ## [1.0.5](https://github.com/getbouncer/react-native-cardscan/tree/1.0.5) (2020-05-19) 138 | 139 | **Merged pull requests:** 140 | 141 | - Clean up android [\#8](https://github.com/getbouncer/react-native-cardscan/pull/8) ([awushensky](https://github.com/awushensky)) 142 | - Bump react-native from 0.59.10 to 0.62.2 [\#7](https://github.com/getbouncer/react-native-cardscan/pull/7) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview)) 143 | 144 | ## [1.0.5147](https://github.com/getbouncer/react-native-cardscan/tree/1.0.5147) (2020-04-27) 145 | 146 | **Merged pull requests:** 147 | 148 | - Pin versions of cardscan [\#6](https://github.com/getbouncer/react-native-cardscan/pull/6) ([awushensky](https://github.com/awushensky)) 149 | - Bump acorn from 5.7.3 to 5.7.4 in /example [\#5](https://github.com/getbouncer/react-native-cardscan/pull/5) ([dependabot[bot]](https://github.com/apps/dependabot)) 150 | - changed ios install path to new github repo name [\#4](https://github.com/getbouncer/react-native-cardscan/pull/4) ([jaimejiyepark](https://github.com/jaimejiyepark)) 151 | - \[bugfix\] Allow expiry month and year to be null [\#3](https://github.com/getbouncer/react-native-cardscan/pull/3) ([zeulb](https://github.com/zeulb)) 152 | - making repo open [\#2](https://github.com/getbouncer/react-native-cardscan/pull/2) ([jaimejiyepark](https://github.com/jaimejiyepark)) 153 | - updating README.md [\#1](https://github.com/getbouncer/react-native-cardscan/pull/1) ([jaimejiyepark](https://github.com/jaimejiyepark)) 154 | 155 | 156 | 157 | \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* 158 | -------------------------------------------------------------------------------- /Contributor License Agreement: -------------------------------------------------------------------------------- 1 | Bouncer 2 | Individual and Entity Contributor License Agreement 3 | 4 | Thank you for your interest in contributing to software projects managed by Bouncer Technologies, 5 | Inc. (“We”, “Us” or “Our”). This Contributor License Agreement (“Agreement”) documents the rights 6 | granted by contributors to Us. This Agreement is for your protection as a contributor as well as for 7 | our protection; it does not change your rights to use your own Contributions for any other purpose. 8 | To make this document effective, please read the Agreement carefully and then (i) sign it and send 9 | it to Us by email (PDF) at [insert email address] or (ii) submit it to us electronically, in either 10 | case by following the instructions at [insert hyperlink]. By signing this Agreement (including by 11 | clicking “I agree” and submitting it to us electronically), You are creating a legally binding 12 | contract. If You are less than eighteen years old, please have Your parents or guardian sign the 13 | Agreement. This Agreement covers all future Contributions from You, and may cover more than one 14 | software project managed by Us. 15 | 16 | 1. Definitions 17 | -------------- 18 | “Affiliates” means other Legal Entities that control, are controlled by, or under common control 19 | with that Legal Entity. For the purposes of this definition, “control” means (i) the power, direct 20 | or indirect, to cause the direction or management of such Legal Entity, whether by contract or 21 | otherwise, (ii) ownership of fifty percent (50%) or more of the outstanding shares or securities 22 | which vote to elect the management or other persons who direct such Legal Entity or (iii) beneficial 23 | ownership of such entity. 24 | 25 | “Contribution” means any work of authorship that is Submitted by You to Us in which You own or 26 | assert ownership of the Copyright. By Submitting any Contribution, you represent that You own the 27 | Copyright in the entire work of authorship, or that you otherwise are legally entitled to Submit the 28 | Contribution and to grant the licenses in this Agreement. 29 | 30 | “Copyright” means all rights protecting works of authorship owned or controlled by You or your 31 | Affiliates (as may be applicable), including copyright, moral and related (or neighboring) rights, 32 | as appropriate, for the full term of their existence, including any extensions by You. 33 | 34 | “Effective Date” means the date You execute this Agreement or the date You first Submit a 35 | Contribution to Us, whichever is earlier. 36 | 37 | “Legal Entity” means an entity which is not a natural person. 38 | 39 | “Material” means the work of authorship which is made available by Us to third parties. When this 40 | Agreement covers more than one software project, the Material means the work of authorship to which 41 | the Contribution was Submitted. After You Submit the Contribution, it may be included in the 42 | Material. 43 | 44 | “Media” means any portion of a Contribution which is not software. 45 | 46 | “Submit” means any form of electronic, verbal, or written communication sent to Us or our 47 | representatives at a destination (including websites) that we own or control or that is otherwise 48 | registered to us, including but not limited to electronic mailing lists, source code control 49 | systems, instant messages or similar communications, and issue tracking systems that are managed by, 50 | or on behalf of, Us for the purpose of discussing and improving the Material, but excluding any 51 | communication that is conspicuously marked or otherwise designated in writing by You as “Not a 52 | Contribution.” 53 | 54 | “Submission Date” means the date on which You Submit a Contribution to Us. 55 | 56 | “You” (entity). If You are an individual acting on your own behalf, then “You” means the individual 57 | who Submits a Contribution to Us. 58 | 59 | “You” (individual). If You are Submitting any Contribution on behalf of any entity, then “You” means 60 | the Legal Entity on behalf of whom you Submit a Contribution to Us. 61 | 62 | 63 | 2. Grant of Rights 64 | ------------------ 65 | 2.1 Copyright License 66 | (a) Except for the license granted to Us in this Agreement, You reserve all right, title, and 67 | interest in and to Your Contributions. That means that you can keep doing whatever you want with 68 | your Contribution, and you can license it to anyone you want under any terms you want. 69 | 70 | (b) To the maximum extent permitted by the relevant law, You grant to Us a perpetual, worldwide, 71 | non-exclusive, transferable, no charge and royalty-free, irrevocable license under the Copyright 72 | covering the Contribution, with the right to sublicense such rights through multiple tiers of 73 | sublicensees, to reproduce, modify, display, perform, sublicense and distribute the Contribution as 74 | part of the Material; provided that this license is subject to Section 2.3. 75 | 76 | 2.2 Patent License 77 | For patent claims including, without limitation, method, process, and apparatus claims which You (or 78 | your Affiliates, as may be applicable) own, control or have the right to grant, now or in the 79 | future, You grant to Us a perpetual, worldwide, non-exclusive, transferable, no charge and royalty- 80 | free, irrevocable patent license, with the right to sublicense these rights to multiple tiers of 81 | sublicensees, to make, have made, use, sell, offer for sale, import and otherwise transfer the 82 | Contribution (and the Contribution in combination with the Material, and portions of such 83 | combination). This license is granted only to the extent that the exercise of the licensed rights 84 | infringes such patent claims; and is subject to Section 2.3. If any person institutes patent 85 | litigation against Contributor or any other entity (including a cross-claim or counterclaim in a 86 | lawsuit) alleging that the Contributions, or the Project to which the Contributions were submitted, 87 | constitutes direct or contributory patent infringement, then any patent licenses granted under this 88 | Agreement for that Contribution to the person or entity instituting the litigation, or the Project 89 | to which the Contributions were submitted, shall terminate as of the date such litigation is filed. 90 | 91 | 2.3 Outbound License 92 | Based on the grant of rights in Sections 2.1 (meaning, no matter what, you can keep licensing your 93 | Contribution to others however you want) and 2.2, if We include Your Contribution in any Material, 94 | and if We determine that it is appropriate for the purpose of commercializing any Material or any 95 | project under Our control, we may license the Contribution under any license, including copyleft, 96 | permissive, commercial, or proprietary licenses. 97 | 98 | 2.4 Moral Rights. 99 | We agree to comply with applicable laws regarding your Contribution, including copyright laws and 100 | law related to moral rights. If moral rights apply to the Contribution, to the maximum extent 101 | permitted by law, You waive and agree not to assert such moral rights against Us or our successors 102 | in interest, or any of our licensees, either direct or indirect. 103 | 104 | 2.5 Our Rights. 105 | You acknowledge that We are not obligated to use Your Contribution as part of any Material, and that 106 | we and may decide to include any Contribution We consider appropriate. 107 | 108 | 2.6 Reservation of Rights. 109 | Any rights in Your Contribution not expressly licensed under this Agreement are expressly reserved 110 | by You. 111 | 112 | 3. Agreement. 113 | ------------- 114 | You confirm that: 115 | 116 | (a) You have the legal authority to enter into this Agreement. If your employer(s) has rights to 117 | intellectual property that you create that includes your Contributions, you represent that you have 118 | received permission to make Contributions on behalf of that employer, and that your employer has 119 | waived such rights for your Contributions to Us. 120 | 121 | (b) You (or your Affiliates, as may be applicable) own or otherwise have the legal right to license 122 | the Copyright and patent claims covering the Contribution which are required to grant the rights 123 | under Section 2. 124 | 125 | (c) The grant of rights under Section 2 does not violate any grant of rights which You (or your 126 | Affiliates, as may be applicable) have made to third parties, including Your employer. 127 | 128 | (d) You represent that each of Your Contributions is Your original work. You represent that Your 129 | Contribution submissions include complete details of any third-party license or other restriction 130 | (including, but not limited to, related patents and trademarks) of which you are personally aware 131 | and which are associated with any part of Your Contributions. 132 | 133 | (e) You agree to notify Us of any facts or circumstances of which you become aware that would make 134 | these representations inaccurate in any respect. 135 | 136 | 4. Disclaimer 137 | ------------- 138 | EXCEPT FOR THE EXPRESS WARRANTIES IN SECTION 3, THE CONTRIBUTION IS PROVIDED "AS IS". YOU EXPRESSLY 139 | DISCLAIM ALL EXPRESS OR IMPLIED WARRANTIES INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY OF 140 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. TO THE EXTENT THAT ANY SUCH 141 | WARRANTIES CANNOT BE DISCLAIMED, SUCH WARRANTY IS LIMITED IN DURATION TO THE MINIMUM PERIOD 142 | PERMITTED BY LAW. 143 | 144 | 5. Consequential Damage Waiver 145 | ------------------------------ 146 | TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL YOU OR WE BE LIABLE FOR ANY LOSS 147 | OF PROFITS, LOSS OF ANTICIPATED SAVINGS, LOSS OF DATA, INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL 148 | AND EXEMPLARY DAMAGES ARISING OUT OF THIS AGREEMENT REGARDLESS OF THE LEGAL OR EQUITABLE THEORY 149 | (CONTRACT, TORT OR OTHERWISE) UPON WHICH THE CLAIM IS BASED. 150 | 151 | 6. Miscellaneous 152 | ---------------- 153 | 6.1 This Agreement will be governed by and construed in accordance with the laws of the State of 154 | California, without regard to conflicts of law provisions. The sole venue for all disputes relating 155 | to this Agreement shall be in Alameda County, California. The rights and obligations of the parties 156 | under this Agreement shall not be governed by the 1980 U.N. Convention on Contracts for the 157 | International Sale of Goods. 158 | 159 | 6.2 This Agreement may be amended only by a written document signed by the party against whom 160 | enforcement is sought. 161 | 162 | 6.3 The failure of either party to require performance by the other party of any provision of this 163 | Agreement in one situation shall not affect the right of a party to require such performance at any 164 | time in the future. A waiver of performance under a provision in one situation shall not be 165 | considered a waiver of the performance of the provision in the future or a waiver of the provision 166 | in its entirety. 167 | 168 | 6.4 If any provision of this Agreement is found void and unenforceable, such provision will be 169 | replaced to the extent possible with a provision that comes closest to the meaning of the original 170 | provision and which is enforceable. The terms and conditions set forth in this Agreement shall apply 171 | notwithstanding any failure of essential purpose of this Agreement or any limited remedy to the 172 | maximum extent possible under law. 173 | 174 | This Agreement contains the entire understanding of the parties regarding the subject matter of this 175 | Agreement and supersedes all prior and contemporaneous negotiations and agreements, whether written 176 | or oral, between the parties with respect to the subject matter of this Agreement. 177 | 178 | By signing below, Contributor accepts and agrees to the preceding terms and conditions for 179 | Contributor’s present and future Contributions submitted to Us. 180 | 181 | 182 | ________________________________________ 183 | Signature 184 | 185 | ________________________________________ 186 | Contributor Name 187 | 188 | ________________________________________ 189 | Legal Entity Name (if applicable) 190 | 191 | ________________________________________ 192 | Contributor Address 193 | 194 | ________________________________________ 195 | Title 196 | 197 | ________________________________________ 198 | Contributor Address 199 | 200 | ________________________________________ 201 | Email 202 | 203 | ________________________________________ 204 | Telephone 205 | 206 | ________________________________________ 207 | Date 208 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Bouncer Technologies, Inc. 2 | No-Cost Software License Agreement 3 | 4 | IMPORTANT - READ CAREFULLY. THIS BOUNCER TECHNOLOGIES, INC. NO-COST SOFTWARE LICENSE AGREEMENT 5 | (“AGREEMENT”) SETS FORTH THE LEGAL TERMS AND CONDITIONS WHICH GOVERN RELATIONSHIP BETWEEN BOUNCER 6 | TECHNOLOGIES, INC. (THE “COMPANY”) AND THE OTHER PERSON OR ENTITY AGREEING TO THIS AGREEMENT (“YOU”) 7 | WITH RESPECT TO ANY COMPANY SOFTWARE OR SAAS PRODUCT (“SOFTWARE”) YOU DOWNLOAD OR ACCESS. IF YOU 8 | EXERCISE ANY OF THE LICENSED RIGHTS IN THIS AGREEMENT, THEN (1) YOU ARE DEEMED TO HAVE ACCEPTED AND 9 | AGREED TO ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT AND (2) YOU REPRESENT THAT YOU ARE 10 | AUTHORIZED TO ACCEPT AND AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND YOU INTEND TO ENTER 11 | INTO AND TO BE BOUND BY THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO ALL OF 12 | THE TERMS AND CONDITIONS OF THIS AGREEMENT, THEN YOU HAVE NO RIGHTS IN THE SOFTWARE AND YOU MAY NOT 13 | USE THE SOFTWARE IN ANY WAY. 14 | 15 | 1. Grant of Rights; Restrictions. 16 | --------------------------------- 17 | a. Grant of Rights. Subject to the terms and conditions of this Agreement, and solely during the 18 | License Term (as defined in this paragraph), the Company hereby grants to You a limited, personal, 19 | non-exclusive, non-transferable, non-assignable and non-sublicensable license to: (i) install on a 20 | server and internally run and use the Software; and (ii) use the documentation, training materials 21 | or other materials supplied by the Company to enable such internal use, in each case subject to the 22 | restrictions set forth in this Agreement. For purposes of this Agreement, “License Term” means 23 | (i) 90 calendar days from the date you first downloaded or accessed the Software or any part of it 24 | in the case of any commercial or production use of the Software, and (ii) perpetual (subject to 25 | continued compliance with this Agreement) in the case of solely non-commercial, non-production use 26 | of the Software. 27 | 28 | b. Documentation. You will have access to Software documentation as determined solely by the 29 | Company. All of the documentation provided to You pursuant to this Agreement is copyright Bouncer 30 | Technologies, Inc., and is licensed to You solely for Your use during the term of this Agreement. 31 | You do not have the right to copy or redistribute the documentation. The Company retains all rights 32 | in the documentation not expressly granted to You. 33 | 34 | c. Restrictions. You shall not: (i) permit direct or indirect access to, or use of, the Software in 35 | a way that circumvents a contractual usage limit or restricts or disables any functionality of the 36 | Software; (ii) copy the Software or any part, feature, function or user interface thereof (except as 37 | expressly otherwise permitted under this Agreement; (iii) access or use any Software in order to 38 | build a competitive product or service; (iv) remove, alter or obscure any of the Company’s (or its 39 | licensors’) copyright notices, proprietary legends, trademark or service mark attributions, patent 40 | markings or other indicia of the Company’s (or its licensors’) ownership or contribution from the 41 | Software or (v) if at any time you use the Software in any commercial or production environment, use 42 | the Software or any part of it for more than 90 days from the date you first downloaded or accessed 43 | the Software or any part of it. 44 | 45 | 2. Feedback; Contributions 46 | -------------------------- 47 | You are encouraged, though not required, to contribute proposed code, suggestions or other 48 | submissions or feedback to the Company related to the Software. In addition, You agree to use 49 | reasonable efforts to report to the Company any “bugs” or reproducible errors in the Software as 50 | they are encountered. Any information or feedback You may provide to Company related to the Software 51 | or this Agreement is non-confidential and You grant to the Company a non-exclusive, worldwide, fully 52 | paid up, perpetual and irrevocable license to use this information/feedback in Company’s business 53 | activities without restriction and without payment or accounting to You or any third party. Any 54 | submissions of code You may provide must be done via the Company’s website and will be subject to 55 | the Company’s then-current form of Contributor License Agreement. 56 | 57 | 3. Intellectual Property Ownership. 58 | ----------------------------------- 59 | a. Ownership of Intellectual Property. The Software contains proprietary and confidential 60 | information of the Company and its licensors. Except to the extent licenses are expressly granted 61 | hereunder, each party and each party’s licensors, respectively, retains all right, title and 62 | interest in and to all patent, trademark, trade secret rights, inventions, copyrights, know-how and 63 | trade secrets in and to that party’s respective products and services. The Company retains all 64 | right, title and interest in and to any work product created by the Company in the course of 65 | providing the Software and any service or support under this Agreement. In addition, any additional 66 | system software, and the content, organization, graphics, design, compilation, know-how, concepts, 67 | methodologies, procedures, and other matters related to the Company’s website are protected under 68 | applicable copyrights, trademarks and other proprietary rights. The use, copying, redistribution, 69 | use or publication by You of any such parts of the website is prohibited. 70 | 71 | 4. Your Data. 72 | ------------- 73 | “Your Data” means information, content and data provided by You or on Your behalf and made available 74 | or otherwise distributed through use of the Software. You own Your Data. The Company shall have the 75 | right to collect and analyze Your Data and other information relating to the provision, use and 76 | performance of various aspects of the Software and related systems and technologies (including, 77 | without limitation, information concerning Your use of the Software and data derived therefrom), and 78 | the Company will be free (during and after the term hereof) to (i) use such information and data for 79 | the purpose of analytics and to improve and enhance the Software and for other development, 80 | diagnostic and corrective purposes in connection with the Software and other Company offerings, and 81 | (ii) disclose such data solely in aggregate or other de-identified form in connection with its 82 | business. Despite the foregoing, You agree that You will not provide to the Company any Personal 83 | Information. “Personal Information” means information, content and data which can be used to 84 | identify any individual. 85 | 86 | 5. No Indemnities; No Warranties; No Support. 87 | --------------------------------------------- 88 | THIS AGREEMENT DOES NOT ENTITLE YOU TO ANY INDEMNIFICATION OF ANY KIND. THE SOFTWARE AND 89 | DOCUMENTATION ARE LICENSED "AS IS." THE COMPANY MAKES NO WARRANTIES – EXPRESS, IMPLIED, STATUTORY OR 90 | OTHERWISE – WITH RESPECT TO THE SOFTWARE AND DOCUMENTATION, AND EXPRESSLY DISCLAIMS ALL IMPLIED 91 | WARRANTIES INCLUDING BUT NOT LIMITED TO WARRANTIES OF NONINFRINGEMENT, MERCHANTABILITY AND FITNESS 92 | FOR A PARTICULAR PURPOSE. THE COMPANY DOES NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR 93 | ERROR-FREE, OR SUCCEED IN RESOLVING ANY PROBLEM. YOU AGREE THAT USE OF THE SOFTWARE IS AT YOUR OWN 94 | RISK. NEITHER THIS AGREEMENT NOR YOUR ACCESS TO THE SOFTWARE ENTITLE YOU TO RECEIVE SUPPORT SERVICES 95 | FROM THE COMPANY FOR THE SOFTWARE. 96 | 97 | 6. Limitation of Liability. 98 | --------------------------- 99 | TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT SHALL THE COMPANY BE LIABLE FOR ANY DIRECT OR 100 | INDIRECT DAMAGES, INCLUDING INTERRUPTION OF USE OR LOSS OR CORRUPTION OF DATA, LOST REVENUE OR 101 | PROFITS, COST OF COVER OR OTHER SPECIAL, INCIDENTAL, CONSEQUENTIAL, DIRECT, INDIRECT, OR PUNITIVE 102 | DAMAGES ARISING FROM THE USE OF THE SOFTWARE, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF 103 | LIABILITY. IN NO EVENT SHALL THE COMPANY’S LIABILITY, WHETHER BASED IN CONTRACT, TORT (INCLUDING 104 | NEGLIGENCE) OR OTHERWISE, EXCEED THE GREATER OF THE AMOUNT PAID FOR THE SOFTWARE UNDER THIS 105 | AGREEMENT OR FIFTY DOLLARS ($50.00). THE FOREGOING LIMITATIONS WILL APPLY EVEN IF YOU HAVE BEEN 106 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE PARTIES ACKNOWLEDGE THAT THIS IS A REASONABLE 107 | ALLOCATION OF RISK. 108 | 109 | 7. Termination. 110 | --------------- 111 | a. Termination. This Agreement will terminate automatically at the end of the License Term. In 112 | addition, either party may terminate the Agreement at any time by giving the other party written 113 | notice of termination. 114 | 115 | b. Effect of Termination. Upon termination or expiration of this Agreement, all licensed granted 116 | hereunder shall cease. Substantially concurrent with the end of the License Term or any earlier 117 | termination of this Agreement, You shall remove the Software (by deleting the Software and all 118 | copies thereof) from Your premises, and any copies of it made by You, unless the Company gives You 119 | written authorization before close of the License Term or any earlier termination to retain 120 | possession of the Software and copies for a longer time period. 121 | 122 | c. Survival. The following sections shall survive any termination of this Agreement: 123 | 1(b), 1(c), 2-6, 7(b), 7(c) and 8-11 and all associated definitions. 124 | 125 | 8. Relationship of the Parties. 126 | ------------------------------- 127 | Nothing in this Agreement will be construed to create a partnership, joint venture or agency 128 | relationship between the parties. The parties agree that each is an independent contractor and 129 | neither party will have the power to bind the other or to incur obligations on the other’s behalf 130 | without such other party’s prior written consent. 131 | 132 | 9. Export Regulations. 133 | ---------------------- 134 | The Software is subject to U.S. export controls, specifically the Export Administration Regulations. 135 | Both parties shall comply with all relevant import and export regulations, including those adopted 136 | by the Bureau of Industry and Security of the U.S. Department of Commerce. You shall not transfer, 137 | export or re-export, directly or indirectly, the Software to any Prohibited Entity, and You affirms 138 | that You are not a Prohibited Entity or acting on behalf of any Prohibited Entity (as defined under 139 | U.S. laws and regulations). 140 | 141 | 10. No License to Government Entities. 142 | -------------------------------------- 143 | This Agreement is not intended to grant any license to any government entity. If You represent any 144 | entity associated with any national, state or local government, please contact the Company to 145 | discuss license terms for the Software. 146 | 147 | 11. Miscellaneous. 148 | ------------------ 149 | Neither party hereto shall be liable for any breach of its obligations hereunder resulting from 150 | causes beyond its reasonable control including but not limited to fires, floods, earthquakes, 151 | pandemic or epidemic illness, strikes (of its own or other employees), insurrection or riots, 152 | embargoes, requirements or regulations of any civil or military authority. All notices required or 153 | permitted under this Agreement will be in writing, will reference this Agreement, and will be deemed 154 | given: (i) when delivered personally; (ii) one business day after deposit with a 155 | nationally-recognized express courier, with written confirmation of receipt; or (iii) three business 156 | days after having been sent by registered or certified mail, return receipt requested, postage 157 | prepaid; or (iv) on the date of receipt, when delivered by email. This Agreement is not assignable 158 | or transferable by You without the Company’s prior written consent. No failure or delay in 159 | exercising any right hereunder will operate as a waiver, thereof, nor will any partial exercise of 160 | any right or power hereunder preclude further exercise. If any provision of this Agreement is held 161 | to be unenforceable, this Agreement will remain in effect with the provision omitted, unless 162 | omission would frustrate the intent of the parties, in which case this Agreement will immediately 163 | terminate. This Agreement may be modified, replaced or rescinded only in writing and signed by a 164 | duly authorized representative of each party. This Agreement shall be construed under and governed 165 | by the laws of the State of California, without regard to conflict of law provisions. The sole venue 166 | for any dispute, claim or controversy arising out of or relating to this Agreement shall be in the 167 | courts of Alameda County, California. If any legal action or other proceeding is brought to enforce 168 | the provisions of this Agreement, the prevailing party shall be entitled to recover reasonable 169 | attorney fees and other costs incurred in the action or proceeding, in addition to any other relief 170 | to which the prevailing party may be entitled. 171 | 172 | THIS AGREEMENT SUPERSEDES ALL PRIOR OR CONTEMPORANEOUS ORAL OR WRITTEN COMMUNICATIONS, PROPOSALS, 173 | REPRESENTATIONS AND WARRANTIES AND PREVAILS OVER ANY CONFLICTING OR ADDITIONAL TERMS OF ANY QUOTE, 174 | PURCHASE ORDER, ACKNOWLEDGMENT, OR OTHER COMMUNICATION BETWEEN THE PARTIES RELATING TO ITS SUBJECT 175 | MATTER DURING THE TERM OF THIS AGREEMENT. 176 | -------------------------------------------------------------------------------- /ios/RNCardscan.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 52; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | F3368C4426FC5F8E001635E5 /* CardScan in Frameworks */ = {isa = PBXBuildFile; productRef = F3368C4326FC5F8E001635E5 /* CardScan */; }; 11 | /* End PBXBuildFile section */ 12 | 13 | /* Begin PBXFileReference section */ 14 | F3073B2226FC446100E7FF51 /* RNCardScan.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RNCardScan.app; sourceTree = BUILT_PRODUCTS_DIR; }; 15 | F3368C4926FC6DF5001635E5 /* RNCardScan.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNCardScan.m; sourceTree = ""; }; 16 | F3368C4A26FC6DF6001635E5 /* RNCardScanStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNCardScanStyle.swift; sourceTree = ""; }; 17 | F3368C4B26FC6DF6001635E5 /* RNCardScanViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNCardScanViewController.swift; sourceTree = ""; }; 18 | F3368C4C26FC6DF6001635E5 /* RNCardScan-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RNCardScan-Bridging-Header.h"; sourceTree = ""; }; 19 | F3368C4D26FC6DF6001635E5 /* RNCardScan.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNCardScan.swift; sourceTree = ""; }; 20 | F3368C4E26FC6DF6001635E5 /* UIColor+Hex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Hex.swift"; sourceTree = ""; }; 21 | /* End PBXFileReference section */ 22 | 23 | /* Begin PBXFrameworksBuildPhase section */ 24 | F3073B0326FC40B700E7FF51 /* Frameworks */ = { 25 | isa = PBXFrameworksBuildPhase; 26 | buildActionMask = 2147483647; 27 | files = ( 28 | F3368C4426FC5F8E001635E5 /* CardScan in Frameworks */, 29 | ); 30 | runOnlyForDeploymentPostprocessing = 0; 31 | }; 32 | /* End PBXFrameworksBuildPhase section */ 33 | 34 | /* Begin PBXGroup section */ 35 | 58B511D21A9E6C8500147676 = { 36 | isa = PBXGroup; 37 | children = ( 38 | F3368C4C26FC6DF6001635E5 /* RNCardScan-Bridging-Header.h */, 39 | F3368C4926FC6DF5001635E5 /* RNCardScan.m */, 40 | F3368C4D26FC6DF6001635E5 /* RNCardScan.swift */, 41 | F3368C4A26FC6DF6001635E5 /* RNCardScanStyle.swift */, 42 | F3368C4B26FC6DF6001635E5 /* RNCardScanViewController.swift */, 43 | F3368C4E26FC6DF6001635E5 /* UIColor+Hex.swift */, 44 | F3073B2226FC446100E7FF51 /* RNCardScan.app */, 45 | ); 46 | sourceTree = ""; 47 | }; 48 | /* End PBXGroup section */ 49 | 50 | /* Begin PBXNativeTarget section */ 51 | F3073B0526FC40B700E7FF51 /* RNCardScan */ = { 52 | isa = PBXNativeTarget; 53 | buildConfigurationList = F3073B1426FC40B800E7FF51 /* Build configuration list for PBXNativeTarget "RNCardScan" */; 54 | buildPhases = ( 55 | F3073B0226FC40B700E7FF51 /* Sources */, 56 | F3073B0326FC40B700E7FF51 /* Frameworks */, 57 | F3073B0426FC40B700E7FF51 /* Resources */, 58 | ); 59 | buildRules = ( 60 | ); 61 | dependencies = ( 62 | ); 63 | name = RNCardScan; 64 | packageProductDependencies = ( 65 | F3368C4326FC5F8E001635E5 /* CardScan */, 66 | ); 67 | productName = RNCardScan; 68 | productReference = F3073B2226FC446100E7FF51 /* RNCardScan.app */; 69 | productType = "com.apple.product-type.application"; 70 | }; 71 | /* End PBXNativeTarget section */ 72 | 73 | /* Begin PBXProject section */ 74 | 58B511D31A9E6C8500147676 /* Project object */ = { 75 | isa = PBXProject; 76 | attributes = { 77 | LastSwiftUpdateCheck = 1250; 78 | LastUpgradeCheck = 0920; 79 | ORGANIZATIONNAME = Facebook; 80 | TargetAttributes = { 81 | F3073B0526FC40B700E7FF51 = { 82 | CreatedOnToolsVersion = 12.5; 83 | }; 84 | }; 85 | }; 86 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCardScan" */; 87 | compatibilityVersion = "Xcode 3.2"; 88 | developmentRegion = English; 89 | hasScannedForEncodings = 0; 90 | knownRegions = ( 91 | English, 92 | en, 93 | ); 94 | mainGroup = 58B511D21A9E6C8500147676; 95 | packageReferences = ( 96 | F3368C4226FC5F8E001635E5 /* XCRemoteSwiftPackageReference "cardscan-ios" */, 97 | ); 98 | productRefGroup = 58B511D21A9E6C8500147676; 99 | projectDirPath = ""; 100 | projectRoot = ""; 101 | targets = ( 102 | F3073B0526FC40B700E7FF51 /* RNCardScan */, 103 | ); 104 | }; 105 | /* End PBXProject section */ 106 | 107 | /* Begin PBXResourcesBuildPhase section */ 108 | F3073B0426FC40B700E7FF51 /* Resources */ = { 109 | isa = PBXResourcesBuildPhase; 110 | buildActionMask = 2147483647; 111 | files = ( 112 | ); 113 | runOnlyForDeploymentPostprocessing = 0; 114 | }; 115 | /* End PBXResourcesBuildPhase section */ 116 | 117 | /* Begin PBXSourcesBuildPhase section */ 118 | F3073B0226FC40B700E7FF51 /* Sources */ = { 119 | isa = PBXSourcesBuildPhase; 120 | buildActionMask = 2147483647; 121 | files = ( 122 | ); 123 | runOnlyForDeploymentPostprocessing = 0; 124 | }; 125 | /* End PBXSourcesBuildPhase section */ 126 | 127 | /* Begin XCBuildConfiguration section */ 128 | 58B511ED1A9E6C8500147676 /* Debug */ = { 129 | isa = XCBuildConfiguration; 130 | buildSettings = { 131 | ALWAYS_SEARCH_USER_PATHS = NO; 132 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 133 | CLANG_CXX_LIBRARY = "libc++"; 134 | CLANG_ENABLE_MODULES = YES; 135 | CLANG_ENABLE_OBJC_ARC = YES; 136 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 137 | CLANG_WARN_BOOL_CONVERSION = YES; 138 | CLANG_WARN_COMMA = YES; 139 | CLANG_WARN_CONSTANT_CONVERSION = YES; 140 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 141 | CLANG_WARN_EMPTY_BODY = YES; 142 | CLANG_WARN_ENUM_CONVERSION = YES; 143 | CLANG_WARN_INFINITE_RECURSION = YES; 144 | CLANG_WARN_INT_CONVERSION = YES; 145 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 146 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 147 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 148 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 149 | CLANG_WARN_STRICT_PROTOTYPES = YES; 150 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 151 | CLANG_WARN_UNREACHABLE_CODE = YES; 152 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 153 | COPY_PHASE_STRIP = NO; 154 | ENABLE_STRICT_OBJC_MSGSEND = YES; 155 | ENABLE_TESTABILITY = YES; 156 | GCC_C_LANGUAGE_STANDARD = gnu99; 157 | GCC_DYNAMIC_NO_PIC = NO; 158 | GCC_NO_COMMON_BLOCKS = YES; 159 | GCC_OPTIMIZATION_LEVEL = 0; 160 | GCC_PREPROCESSOR_DEFINITIONS = ( 161 | "DEBUG=1", 162 | "$(inherited)", 163 | ); 164 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 165 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 166 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 167 | GCC_WARN_UNDECLARED_SELECTOR = YES; 168 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 169 | GCC_WARN_UNUSED_FUNCTION = YES; 170 | GCC_WARN_UNUSED_VARIABLE = YES; 171 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 172 | MTL_ENABLE_DEBUG_INFO = YES; 173 | ONLY_ACTIVE_ARCH = YES; 174 | SDKROOT = iphoneos; 175 | }; 176 | name = Debug; 177 | }; 178 | 58B511EE1A9E6C8500147676 /* Release */ = { 179 | isa = XCBuildConfiguration; 180 | buildSettings = { 181 | ALWAYS_SEARCH_USER_PATHS = NO; 182 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 183 | CLANG_CXX_LIBRARY = "libc++"; 184 | CLANG_ENABLE_MODULES = YES; 185 | CLANG_ENABLE_OBJC_ARC = YES; 186 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 187 | CLANG_WARN_BOOL_CONVERSION = YES; 188 | CLANG_WARN_COMMA = YES; 189 | CLANG_WARN_CONSTANT_CONVERSION = YES; 190 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 191 | CLANG_WARN_EMPTY_BODY = YES; 192 | CLANG_WARN_ENUM_CONVERSION = YES; 193 | CLANG_WARN_INFINITE_RECURSION = YES; 194 | CLANG_WARN_INT_CONVERSION = YES; 195 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 196 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 197 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 198 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 199 | CLANG_WARN_STRICT_PROTOTYPES = YES; 200 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 201 | CLANG_WARN_UNREACHABLE_CODE = YES; 202 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 203 | COPY_PHASE_STRIP = YES; 204 | ENABLE_NS_ASSERTIONS = NO; 205 | ENABLE_STRICT_OBJC_MSGSEND = YES; 206 | GCC_C_LANGUAGE_STANDARD = gnu99; 207 | GCC_NO_COMMON_BLOCKS = YES; 208 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 209 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 210 | GCC_WARN_UNDECLARED_SELECTOR = YES; 211 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 212 | GCC_WARN_UNUSED_FUNCTION = YES; 213 | GCC_WARN_UNUSED_VARIABLE = YES; 214 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 215 | MTL_ENABLE_DEBUG_INFO = NO; 216 | SDKROOT = iphoneos; 217 | VALIDATE_PRODUCT = YES; 218 | }; 219 | name = Release; 220 | }; 221 | F3073B1226FC40B800E7FF51 /* Debug */ = { 222 | isa = XCBuildConfiguration; 223 | buildSettings = { 224 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 225 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 226 | CLANG_ANALYZER_NONNULL = YES; 227 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 228 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 229 | CLANG_ENABLE_OBJC_WEAK = YES; 230 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 231 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 232 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 233 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 234 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 235 | CODE_SIGN_STYLE = Automatic; 236 | DEBUG_INFORMATION_FORMAT = dwarf; 237 | DEVELOPMENT_ASSET_PATHS = ""; 238 | DEVELOPMENT_TEAM = Y28TH9SHX7; 239 | ENABLE_PREVIEWS = YES; 240 | GCC_C_LANGUAGE_STANDARD = gnu11; 241 | HEADER_SEARCH_PATHS = ( 242 | "$(inherited)", 243 | "\"${PODS_ROOT}/Headers/Public\"", 244 | "\"${PODS_ROOT}/Headers/Public/React-Core\"", 245 | ); 246 | INFOPLIST_FILE = RNCardScan/Info.plist; 247 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 248 | LD_RUNPATH_SEARCH_PATHS = ( 249 | "$(inherited)", 250 | "@executable_path/Frameworks", 251 | ); 252 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 253 | MTL_FAST_MATH = YES; 254 | PRODUCT_BUNDLE_IDENTIFIER = com.stripe.RNCardScan; 255 | PRODUCT_NAME = "$(TARGET_NAME)"; 256 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 257 | SWIFT_OBJC_BRIDGING_HEADER = "RNCardScan/Source/RNCardScan-Bridging-Header.h"; 258 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 259 | SWIFT_VERSION = 5.0; 260 | TARGETED_DEVICE_FAMILY = "1,2"; 261 | }; 262 | name = Debug; 263 | }; 264 | F3073B1326FC40B800E7FF51 /* Release */ = { 265 | isa = XCBuildConfiguration; 266 | buildSettings = { 267 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 268 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 269 | CLANG_ANALYZER_NONNULL = YES; 270 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 271 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 272 | CLANG_ENABLE_OBJC_WEAK = YES; 273 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 274 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 275 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 276 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 277 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 278 | CODE_SIGN_STYLE = Automatic; 279 | COPY_PHASE_STRIP = NO; 280 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 281 | DEVELOPMENT_ASSET_PATHS = ""; 282 | DEVELOPMENT_TEAM = Y28TH9SHX7; 283 | ENABLE_PREVIEWS = YES; 284 | GCC_C_LANGUAGE_STANDARD = gnu11; 285 | HEADER_SEARCH_PATHS = ( 286 | "$(inherited)", 287 | "\"${PODS_ROOT}/Headers/Public\"", 288 | "\"${PODS_ROOT}/Headers/Public/React-Core\"", 289 | ); 290 | INFOPLIST_FILE = RNCardScan/Info.plist; 291 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 292 | LD_RUNPATH_SEARCH_PATHS = ( 293 | "$(inherited)", 294 | "@executable_path/Frameworks", 295 | ); 296 | MTL_FAST_MATH = YES; 297 | PRODUCT_BUNDLE_IDENTIFIER = com.stripe.RNCardScan; 298 | PRODUCT_NAME = "$(TARGET_NAME)"; 299 | SWIFT_COMPILATION_MODE = wholemodule; 300 | SWIFT_OBJC_BRIDGING_HEADER = "RNCardScan/Source/RNCardScan-Bridging-Header.h"; 301 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 302 | SWIFT_VERSION = 5.0; 303 | TARGETED_DEVICE_FAMILY = "1,2"; 304 | }; 305 | name = Release; 306 | }; 307 | /* End XCBuildConfiguration section */ 308 | 309 | /* Begin XCConfigurationList section */ 310 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCardScan" */ = { 311 | isa = XCConfigurationList; 312 | buildConfigurations = ( 313 | 58B511ED1A9E6C8500147676 /* Debug */, 314 | 58B511EE1A9E6C8500147676 /* Release */, 315 | ); 316 | defaultConfigurationIsVisible = 0; 317 | defaultConfigurationName = Release; 318 | }; 319 | F3073B1426FC40B800E7FF51 /* Build configuration list for PBXNativeTarget "RNCardScan" */ = { 320 | isa = XCConfigurationList; 321 | buildConfigurations = ( 322 | F3073B1226FC40B800E7FF51 /* Debug */, 323 | F3073B1326FC40B800E7FF51 /* Release */, 324 | ); 325 | defaultConfigurationIsVisible = 0; 326 | defaultConfigurationName = Release; 327 | }; 328 | /* End XCConfigurationList section */ 329 | 330 | /* Begin XCRemoteSwiftPackageReference section */ 331 | F3368C4226FC5F8E001635E5 /* XCRemoteSwiftPackageReference "cardscan-ios" */ = { 332 | isa = XCRemoteSwiftPackageReference; 333 | repositoryURL = "https://github.com/getbouncer/cardscan-ios.git"; 334 | requirement = { 335 | kind = upToNextMajorVersion; 336 | minimumVersion = 2.1.2; 337 | }; 338 | }; 339 | /* End XCRemoteSwiftPackageReference section */ 340 | 341 | /* Begin XCSwiftPackageProductDependency section */ 342 | F3368C4326FC5F8E001635E5 /* CardScan */ = { 343 | isa = XCSwiftPackageProductDependency; 344 | package = F3368C4226FC5F8E001635E5 /* XCRemoteSwiftPackageReference "cardscan-ios" */; 345 | productName = CardScan; 346 | }; 347 | /* End XCSwiftPackageProductDependency section */ 348 | }; 349 | rootObject = 58B511D31A9E6C8500147676 /* Project object */; 350 | } 351 | -------------------------------------------------------------------------------- /example/ios/example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 11 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 12 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 14 | 7B8A99472374F1F3000CD038 /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B8A99462374F1F3000CD038 /* File.swift */; }; 15 | E310ACF1DBF071A8EB7908DF /* libPods-example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 716FB28B6DD7DDAD9D9EE40F /* libPods-example.a */; }; 16 | ED297163215061F000B7C4FE /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED297162215061F000B7C4FE /* JavaScriptCore.framework */; }; 17 | F30707C024B900CC00C64C11 /* libReact-RCTBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F30707BF24B900CC00C64C11 /* libReact-RCTBlob.a */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; 22 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 23 | 00E356F21AD99517003FC87E /* exampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = exampleTests.m; sourceTree = ""; }; 24 | 0A330FC4DAE36BDDB8815A13 /* Pods-example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.debug.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.debug.xcconfig"; sourceTree = ""; }; 25 | 13B07F961A680F5B00A75B9A /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 26 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = example/AppDelegate.h; sourceTree = ""; }; 27 | 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = example/AppDelegate.m; sourceTree = ""; }; 28 | 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 29 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = example/Images.xcassets; sourceTree = ""; }; 30 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = example/Info.plist; sourceTree = ""; }; 31 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = example/main.m; sourceTree = ""; }; 32 | 2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | 716FB28B6DD7DDAD9D9EE40F /* libPods-example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | 7B8A99462374F1F3000CD038 /* File.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = File.swift; path = example/File.swift; sourceTree = ""; }; 35 | 7B8FCF142374BFE2004DE8C1 /* example-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "example-Bridging-Header.h"; sourceTree = ""; }; 36 | D301E790508E5968BD0D429D /* Pods-example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.release.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.release.xcconfig"; sourceTree = ""; }; 37 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; 38 | ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; 39 | F30707B124B8FE5F00C64C11 /* libReact-RCTBlob.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = "libReact-RCTBlob.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | F30707BF24B900CC00C64C11 /* libReact-RCTBlob.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = "libReact-RCTBlob.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | F30707C024B900CC00C64C11 /* libReact-RCTBlob.a in Frameworks */, 49 | ED297163215061F000B7C4FE /* JavaScriptCore.framework in Frameworks */, 50 | E310ACF1DBF071A8EB7908DF /* libPods-example.a in Frameworks */, 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | /* End PBXFrameworksBuildPhase section */ 55 | 56 | /* Begin PBXGroup section */ 57 | 00E356EF1AD99517003FC87E /* exampleTests */ = { 58 | isa = PBXGroup; 59 | children = ( 60 | 00E356F21AD99517003FC87E /* exampleTests.m */, 61 | 00E356F01AD99517003FC87E /* Supporting Files */, 62 | ); 63 | path = exampleTests; 64 | sourceTree = ""; 65 | }; 66 | 00E356F01AD99517003FC87E /* Supporting Files */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | 00E356F11AD99517003FC87E /* Info.plist */, 70 | ); 71 | name = "Supporting Files"; 72 | sourceTree = ""; 73 | }; 74 | 13B07FAE1A68108700A75B9A /* example */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */, 78 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 79 | 13B07FB01A68108700A75B9A /* AppDelegate.m */, 80 | 13B07FB51A68108700A75B9A /* Images.xcassets */, 81 | 13B07FB61A68108700A75B9A /* Info.plist */, 82 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, 83 | 13B07FB71A68108700A75B9A /* main.m */, 84 | 7B8FCF142374BFE2004DE8C1 /* example-Bridging-Header.h */, 85 | ); 86 | name = example; 87 | sourceTree = ""; 88 | }; 89 | 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | F30707BF24B900CC00C64C11 /* libReact-RCTBlob.a */, 93 | F30707B124B8FE5F00C64C11 /* libReact-RCTBlob.a */, 94 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */, 95 | ED2971642150620600B7C4FE /* JavaScriptCore.framework */, 96 | 2D16E6891FA4F8E400B85C8A /* libReact.a */, 97 | 716FB28B6DD7DDAD9D9EE40F /* libPods-example.a */, 98 | ); 99 | name = Frameworks; 100 | sourceTree = ""; 101 | }; 102 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | ); 106 | name = Libraries; 107 | sourceTree = ""; 108 | }; 109 | 83CBB9F61A601CBA00E9B192 = { 110 | isa = PBXGroup; 111 | children = ( 112 | 7B8A99462374F1F3000CD038 /* File.swift */, 113 | 13B07FAE1A68108700A75B9A /* example */, 114 | 832341AE1AAA6A7D00B99B32 /* Libraries */, 115 | 00E356EF1AD99517003FC87E /* exampleTests */, 116 | 83CBBA001A601CBA00E9B192 /* Products */, 117 | 2D16E6871FA4F8E400B85C8A /* Frameworks */, 118 | DE83A140506A281E40F7BD63 /* Pods */, 119 | ); 120 | indentWidth = 2; 121 | sourceTree = ""; 122 | tabWidth = 2; 123 | usesTabs = 0; 124 | }; 125 | 83CBBA001A601CBA00E9B192 /* Products */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 13B07F961A680F5B00A75B9A /* example.app */, 129 | ); 130 | name = Products; 131 | sourceTree = ""; 132 | }; 133 | DE83A140506A281E40F7BD63 /* Pods */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | 0A330FC4DAE36BDDB8815A13 /* Pods-example.debug.xcconfig */, 137 | D301E790508E5968BD0D429D /* Pods-example.release.xcconfig */, 138 | ); 139 | path = Pods; 140 | sourceTree = ""; 141 | }; 142 | /* End PBXGroup section */ 143 | 144 | /* Begin PBXNativeTarget section */ 145 | 13B07F861A680F5B00A75B9A /* example */ = { 146 | isa = PBXNativeTarget; 147 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example" */; 148 | buildPhases = ( 149 | EE2A966579DC463D763075DE /* [CP] Check Pods Manifest.lock */, 150 | 13B07F871A680F5B00A75B9A /* Sources */, 151 | 13B07F8C1A680F5B00A75B9A /* Frameworks */, 152 | 13B07F8E1A680F5B00A75B9A /* Resources */, 153 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 154 | BC16C573C163D0F7BC8CCFCE /* [CP] Embed Pods Frameworks */, 155 | A502DDEA6D876EFB998AE1D1 /* [CP] Copy Pods Resources */, 156 | ); 157 | buildRules = ( 158 | ); 159 | dependencies = ( 160 | ); 161 | name = example; 162 | productName = "Hello World"; 163 | productReference = 13B07F961A680F5B00A75B9A /* example.app */; 164 | productType = "com.apple.product-type.application"; 165 | }; 166 | /* End PBXNativeTarget section */ 167 | 168 | /* Begin PBXProject section */ 169 | 83CBB9F71A601CBA00E9B192 /* Project object */ = { 170 | isa = PBXProject; 171 | attributes = { 172 | LastUpgradeCheck = 0940; 173 | ORGANIZATIONNAME = Facebook; 174 | TargetAttributes = { 175 | 13B07F861A680F5B00A75B9A = { 176 | DevelopmentTeam = L4TQ6C2R74; 177 | LastSwiftMigration = 1120; 178 | }; 179 | }; 180 | }; 181 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "example" */; 182 | compatibilityVersion = "Xcode 3.2"; 183 | developmentRegion = English; 184 | hasScannedForEncodings = 0; 185 | knownRegions = ( 186 | English, 187 | en, 188 | Base, 189 | ); 190 | mainGroup = 83CBB9F61A601CBA00E9B192; 191 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; 192 | projectDirPath = ""; 193 | projectRoot = ""; 194 | targets = ( 195 | 13B07F861A680F5B00A75B9A /* example */, 196 | ); 197 | }; 198 | /* End PBXProject section */ 199 | 200 | /* Begin PBXResourcesBuildPhase section */ 201 | 13B07F8E1A680F5B00A75B9A /* Resources */ = { 202 | isa = PBXResourcesBuildPhase; 203 | buildActionMask = 2147483647; 204 | files = ( 205 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 206 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, 207 | ); 208 | runOnlyForDeploymentPostprocessing = 0; 209 | }; 210 | /* End PBXResourcesBuildPhase section */ 211 | 212 | /* Begin PBXShellScriptBuildPhase section */ 213 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { 214 | isa = PBXShellScriptBuildPhase; 215 | buildActionMask = 2147483647; 216 | files = ( 217 | ); 218 | inputPaths = ( 219 | ); 220 | name = "Bundle React Native code and images"; 221 | outputPaths = ( 222 | ); 223 | runOnlyForDeploymentPostprocessing = 0; 224 | shellPath = /bin/sh; 225 | shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; 226 | }; 227 | A502DDEA6D876EFB998AE1D1 /* [CP] Copy Pods Resources */ = { 228 | isa = PBXShellScriptBuildPhase; 229 | buildActionMask = 2147483647; 230 | files = ( 231 | ); 232 | inputPaths = ( 233 | "${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources.sh", 234 | "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle", 235 | ); 236 | name = "[CP] Copy Pods Resources"; 237 | outputPaths = ( 238 | "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle", 239 | ); 240 | runOnlyForDeploymentPostprocessing = 0; 241 | shellPath = /bin/sh; 242 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources.sh\"\n"; 243 | showEnvVarsInLog = 0; 244 | }; 245 | BC16C573C163D0F7BC8CCFCE /* [CP] Embed Pods Frameworks */ = { 246 | isa = PBXShellScriptBuildPhase; 247 | buildActionMask = 2147483647; 248 | files = ( 249 | ); 250 | inputPaths = ( 251 | "${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-frameworks.sh", 252 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/CardScan/CardScan.framework/CardScan", 253 | ); 254 | name = "[CP] Embed Pods Frameworks"; 255 | outputPaths = ( 256 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CardScan.framework", 257 | ); 258 | runOnlyForDeploymentPostprocessing = 0; 259 | shellPath = /bin/sh; 260 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-frameworks.sh\"\n"; 261 | showEnvVarsInLog = 0; 262 | }; 263 | EE2A966579DC463D763075DE /* [CP] Check Pods Manifest.lock */ = { 264 | isa = PBXShellScriptBuildPhase; 265 | buildActionMask = 2147483647; 266 | files = ( 267 | ); 268 | inputFileListPaths = ( 269 | ); 270 | inputPaths = ( 271 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 272 | "${PODS_ROOT}/Manifest.lock", 273 | ); 274 | name = "[CP] Check Pods Manifest.lock"; 275 | outputFileListPaths = ( 276 | ); 277 | outputPaths = ( 278 | "$(DERIVED_FILE_DIR)/Pods-example-checkManifestLockResult.txt", 279 | ); 280 | runOnlyForDeploymentPostprocessing = 0; 281 | shellPath = /bin/sh; 282 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 283 | showEnvVarsInLog = 0; 284 | }; 285 | /* End PBXShellScriptBuildPhase section */ 286 | 287 | /* Begin PBXSourcesBuildPhase section */ 288 | 13B07F871A680F5B00A75B9A /* Sources */ = { 289 | isa = PBXSourcesBuildPhase; 290 | buildActionMask = 2147483647; 291 | files = ( 292 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, 293 | 7B8A99472374F1F3000CD038 /* File.swift in Sources */, 294 | 13B07FC11A68108700A75B9A /* main.m in Sources */, 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | }; 298 | /* End PBXSourcesBuildPhase section */ 299 | 300 | /* Begin PBXVariantGroup section */ 301 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { 302 | isa = PBXVariantGroup; 303 | children = ( 304 | 13B07FB21A68108700A75B9A /* Base */, 305 | ); 306 | name = LaunchScreen.xib; 307 | path = example; 308 | sourceTree = ""; 309 | }; 310 | /* End PBXVariantGroup section */ 311 | 312 | /* Begin XCBuildConfiguration section */ 313 | 13B07F941A680F5B00A75B9A /* Debug */ = { 314 | isa = XCBuildConfiguration; 315 | baseConfigurationReference = 0A330FC4DAE36BDDB8815A13 /* Pods-example.debug.xcconfig */; 316 | buildSettings = { 317 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 318 | CLANG_ENABLE_MODULES = YES; 319 | CURRENT_PROJECT_VERSION = 1; 320 | DEAD_CODE_STRIPPING = NO; 321 | DEVELOPMENT_TEAM = L4TQ6C2R74; 322 | ENABLE_BITCODE = NO; 323 | INFOPLIST_FILE = example/Info.plist; 324 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 325 | LIBRARY_SEARCH_PATHS = ( 326 | "$(inherited)", 327 | "\"${PODS_CONFIGURATION_BUILD_DIR}/CardScan\"", 328 | "\"${PODS_CONFIGURATION_BUILD_DIR}/DoubleConversion\"", 329 | "\"${PODS_CONFIGURATION_BUILD_DIR}/Folly\"", 330 | "\"${PODS_CONFIGURATION_BUILD_DIR}/React\"", 331 | "\"${PODS_CONFIGURATION_BUILD_DIR}/glog\"", 332 | "\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-cardscan\"", 333 | "\"${PODS_CONFIGURATION_BUILD_DIR}/yoga\"", 334 | ); 335 | OTHER_LDFLAGS = ( 336 | "$(inherited)", 337 | "-ObjC", 338 | "-lc++", 339 | ); 340 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 341 | PRODUCT_NAME = example; 342 | SWIFT_OBJC_BRIDGING_HEADER = "example-Bridging-Header.h"; 343 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 344 | SWIFT_VERSION = 5.0; 345 | USER_HEADER_SEARCH_PATHS = "${PODS_ROOT}/**"; 346 | VERSIONING_SYSTEM = "apple-generic"; 347 | }; 348 | name = Debug; 349 | }; 350 | 13B07F951A680F5B00A75B9A /* Release */ = { 351 | isa = XCBuildConfiguration; 352 | baseConfigurationReference = D301E790508E5968BD0D429D /* Pods-example.release.xcconfig */; 353 | buildSettings = { 354 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 355 | CLANG_ENABLE_MODULES = YES; 356 | CURRENT_PROJECT_VERSION = 1; 357 | DEVELOPMENT_TEAM = L4TQ6C2R74; 358 | INFOPLIST_FILE = example/Info.plist; 359 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 360 | OTHER_LDFLAGS = ( 361 | "$(inherited)", 362 | "-ObjC", 363 | "-lc++", 364 | ); 365 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 366 | PRODUCT_NAME = example; 367 | SWIFT_OBJC_BRIDGING_HEADER = "example-Bridging-Header.h"; 368 | SWIFT_VERSION = 5.0; 369 | USER_HEADER_SEARCH_PATHS = "${PODS_ROOT}/**"; 370 | VERSIONING_SYSTEM = "apple-generic"; 371 | }; 372 | name = Release; 373 | }; 374 | 83CBBA201A601CBA00E9B192 /* Debug */ = { 375 | isa = XCBuildConfiguration; 376 | buildSettings = { 377 | ALWAYS_SEARCH_USER_PATHS = NO; 378 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 379 | CLANG_CXX_LIBRARY = "libc++"; 380 | CLANG_ENABLE_MODULES = YES; 381 | CLANG_ENABLE_OBJC_ARC = YES; 382 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 383 | CLANG_WARN_BOOL_CONVERSION = YES; 384 | CLANG_WARN_COMMA = YES; 385 | CLANG_WARN_CONSTANT_CONVERSION = YES; 386 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 387 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 388 | CLANG_WARN_EMPTY_BODY = YES; 389 | CLANG_WARN_ENUM_CONVERSION = YES; 390 | CLANG_WARN_INFINITE_RECURSION = YES; 391 | CLANG_WARN_INT_CONVERSION = YES; 392 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 393 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 394 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 395 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 396 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 397 | CLANG_WARN_STRICT_PROTOTYPES = YES; 398 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 399 | CLANG_WARN_UNREACHABLE_CODE = YES; 400 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 401 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 402 | COPY_PHASE_STRIP = NO; 403 | ENABLE_STRICT_OBJC_MSGSEND = YES; 404 | ENABLE_TESTABILITY = YES; 405 | GCC_C_LANGUAGE_STANDARD = gnu99; 406 | GCC_DYNAMIC_NO_PIC = NO; 407 | GCC_NO_COMMON_BLOCKS = YES; 408 | GCC_OPTIMIZATION_LEVEL = 0; 409 | GCC_PREPROCESSOR_DEFINITIONS = ( 410 | "DEBUG=1", 411 | "$(inherited)", 412 | ); 413 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 414 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 415 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 416 | GCC_WARN_UNDECLARED_SELECTOR = YES; 417 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 418 | GCC_WARN_UNUSED_FUNCTION = YES; 419 | GCC_WARN_UNUSED_VARIABLE = YES; 420 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 421 | MTL_ENABLE_DEBUG_INFO = YES; 422 | ONLY_ACTIVE_ARCH = YES; 423 | SDKROOT = iphoneos; 424 | }; 425 | name = Debug; 426 | }; 427 | 83CBBA211A601CBA00E9B192 /* Release */ = { 428 | isa = XCBuildConfiguration; 429 | buildSettings = { 430 | ALWAYS_SEARCH_USER_PATHS = NO; 431 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 432 | CLANG_CXX_LIBRARY = "libc++"; 433 | CLANG_ENABLE_MODULES = YES; 434 | CLANG_ENABLE_OBJC_ARC = YES; 435 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 436 | CLANG_WARN_BOOL_CONVERSION = YES; 437 | CLANG_WARN_COMMA = YES; 438 | CLANG_WARN_CONSTANT_CONVERSION = YES; 439 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 440 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 441 | CLANG_WARN_EMPTY_BODY = YES; 442 | CLANG_WARN_ENUM_CONVERSION = YES; 443 | CLANG_WARN_INFINITE_RECURSION = YES; 444 | CLANG_WARN_INT_CONVERSION = YES; 445 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 446 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 447 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 448 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 449 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 450 | CLANG_WARN_STRICT_PROTOTYPES = YES; 451 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 452 | CLANG_WARN_UNREACHABLE_CODE = YES; 453 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 454 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 455 | COPY_PHASE_STRIP = YES; 456 | ENABLE_NS_ASSERTIONS = NO; 457 | ENABLE_STRICT_OBJC_MSGSEND = YES; 458 | GCC_C_LANGUAGE_STANDARD = gnu99; 459 | GCC_NO_COMMON_BLOCKS = YES; 460 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 461 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 462 | GCC_WARN_UNDECLARED_SELECTOR = YES; 463 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 464 | GCC_WARN_UNUSED_FUNCTION = YES; 465 | GCC_WARN_UNUSED_VARIABLE = YES; 466 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 467 | MTL_ENABLE_DEBUG_INFO = NO; 468 | SDKROOT = iphoneos; 469 | VALIDATE_PRODUCT = YES; 470 | }; 471 | name = Release; 472 | }; 473 | /* End XCBuildConfiguration section */ 474 | 475 | /* Begin XCConfigurationList section */ 476 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example" */ = { 477 | isa = XCConfigurationList; 478 | buildConfigurations = ( 479 | 13B07F941A680F5B00A75B9A /* Debug */, 480 | 13B07F951A680F5B00A75B9A /* Release */, 481 | ); 482 | defaultConfigurationIsVisible = 0; 483 | defaultConfigurationName = Release; 484 | }; 485 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "example" */ = { 486 | isa = XCConfigurationList; 487 | buildConfigurations = ( 488 | 83CBBA201A601CBA00E9B192 /* Debug */, 489 | 83CBBA211A601CBA00E9B192 /* Release */, 490 | ); 491 | defaultConfigurationIsVisible = 0; 492 | defaultConfigurationName = Release; 493 | }; 494 | /* End XCConfigurationList section */ 495 | }; 496 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; 497 | } 498 | --------------------------------------------------------------------------------