@vppos/react-native-nfc 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/NFCSDK.podspec +40 -0
- package/android/build.gradle +85 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +31 -0
- package/android/src/main/AndroidManifestNew.xml +30 -0
- package/android/src/main/java/com/nfcsdk/ChipReader.kt +237 -0
- package/android/src/main/java/com/nfcsdk/NFCSDKModule.kt +78 -0
- package/android/src/main/java/com/nfcsdk/NFCSDKPackage.kt +17 -0
- package/android/src/main/java/com/nfcsdk/NFCScanActivity.kt +299 -0
- package/android/src/main/java/com/nfcsdk/utils/Dg13Parser.kt +278 -0
- package/android/src/main/java/com/nfcsdk/utils/FaceExtractor.kt +40 -0
- package/android/src/main/java/com/nfcsdk/utils/MrzUtils.kt +75 -0
- package/android/src/main/res/drawable/bg_nfc_bottom_sheet.xml +13 -0
- package/android/src/main/res/drawable/bg_nfc_sheet_handle.xml +9 -0
- package/android/src/main/res/layout/activity_nfc.xml +110 -0
- package/android/src/main/res/values/styles.xml +10 -0
- package/android/src/main/res/xml/nfc_tech_filter.xml +8 -0
- package/ios/ChipReader.swift +258 -0
- package/ios/NFCSDK-Bridging-Header.h +2 -0
- package/ios/NFCSDK.mm +9 -0
- package/ios/NFCSDK.swift +112 -0
- package/ios/NFCSDKSession.swift +5 -0
- package/ios/utils/DG13Parser.swift +302 -0
- package/ios/utils/MrzUtils.swift +49 -0
- package/lib/module/errors.js +9 -0
- package/lib/module/errors.js.map +1 -0
- package/lib/module/index.js +118 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/errors.d.ts +4 -0
- package/lib/typescript/src/errors.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +80 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +45 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +155 -0
- package/src/errors.ts +6 -0
- package/src/index.tsx +141 -0
- package/src/types.ts +45 -0
- package/vendor/ios-passport-reader/CHANGELOG +362 -0
- package/vendor/ios-passport-reader/CODE_OF_CONDUCT.md +77 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/AppDelegate.swift +39 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/Contents.json +158 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-40.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-72.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-76.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small-50.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small-50@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/ios-marketing.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon~ipad.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon~ipad@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/Contents.json +6 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/background.imageset/Contents.json +21 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/background.imageset/background.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/head.imageset/Contents.json +21 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Assets.xcassets/head.imageset/head.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Base.lproj/LaunchScreen.storyboard +25 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Extensions/FileManagerExt.swift +16 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Extensions/StringExt.swift +40 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Extensions/UIApplicationExt.swift +21 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Info.plist +77 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Model/PassportUtils.swift +76 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Model/SettingsStore.swift +107 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/NFCPassportReader.entitlements +10 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/SceneDelegate.swift +57 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/DetailsView.swift +197 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/ExportPassportView.swift +164 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/HelperViews/CheckBoxView.swift +48 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/HelperViews/ViewExt.swift +20 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/HelperViews/ViewModifiers.swift +41 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/MRZEntryView.swift +125 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/MRZScannerViewController.swift +90 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/MainView.swift +214 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/PassportSummaryView.swift +111 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/PassportView.swift +73 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/SettingsView.swift +63 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/Views/StoredPassportView.swift +152 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/masterList.pem +32 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp/readme.md +10 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp.xcodeproj/project.pbxproj +695 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp.xcodeproj/xcshareddata/xcschemes/NFCPassportReader.xcscheme +106 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp.xcworkspace/contents.xcworkspacedata +10 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderApp.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +8 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderAppTests/DataGroupParsingTests.swift +189 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderAppTests/Info.plist +22 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderAppTests/NFCPassportReaderTests.swift +260 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/NFCPassportReaderAppTests/PACETests.swift +112 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/Podfile +22 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/Podfile.lock +35 -0
- package/vendor/ios-passport-reader/Examples/Example_CocoaPods/README.md +2 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/AppDelegate.swift +39 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/Contents.json +158 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-40.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-72.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-76.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small-50.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small-50@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon-small@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/icon@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/ios-marketing.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon@3x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon~ipad.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/AppIcon.appiconset/notification-icon~ipad@2x.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/Contents.json +6 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/background.imageset/Contents.json +21 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/background.imageset/background.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/head.imageset/Contents.json +21 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Assets.xcassets/head.imageset/head.png +0 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Base.lproj/LaunchScreen.storyboard +25 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Extensions/FileManagerExt.swift +16 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Extensions/StringExt.swift +40 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Extensions/UIApplicationExt.swift +21 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Info.plist +79 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Model/PassportUtils.swift +99 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Model/SettingsStore.swift +98 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Model/SettingsStoreCAN.swift +75 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/MrzScanner/LICENSE +21 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/MrzScanner/PreviewView.swift +34 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/MrzScanner/StringUtils.swift +160 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/MrzScanner/ViewController.swift +320 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/MrzScanner/VisionViewController.swift +163 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/NFCPassportReader.entitlements +10 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/SceneDelegate.swift +58 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/CANViews/CanKeyView.swift +251 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/CANViews/MRZEntryViewCanKey.swift +65 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/CANViews/PassportViewCAN.swift +73 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/DetailsView.swift +193 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/ExportPassportView.swift +164 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/HelperViews/CheckBoxView.swift +48 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/HelperViews/ViewExt.swift +20 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/HelperViews/ViewModifiers.swift +41 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/MRZEntryView.swift +125 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/MRZScannerViewController.swift +90 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/MainView.swift +264 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/PassportSummaryView.swift +111 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/PassportView.swift +73 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/SettingsView.swift +47 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/Views/StoredPassportView.swift +149 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/masterList.pem +32 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/readme.md +10 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp.xcodeproj/project.pbxproj +683 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +25 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp.xcodeproj/xcshareddata/xcschemes/NFCPassportReader.xcscheme +106 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderAppTests/DataGroupParsingTests.swift +190 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderAppTests/Info.plist +22 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderAppTests/NFCPassportReaderTests.swift +260 -0
- package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderAppTests/PACETests.swift +112 -0
- package/vendor/ios-passport-reader/LICENSE +21 -0
- package/vendor/ios-passport-reader/NFCPassportReader.podspec +27 -0
- package/vendor/ios-passport-reader/Package.swift +29 -0
- package/vendor/ios-passport-reader/README.md +141 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/AES_3DES_DESEncryption.swift +377 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/BACHandler.swift +194 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/ChipAuthenticationHandler.swift +224 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroupHash.swift +16 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroupParser.swift +36 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/ActiveAuthenticationInfo.swift +69 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/COM.swift +61 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/CardAccess.swift +38 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/ChipAuthenticationInfo.swift +135 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/ChipAuthenticationPublicKeyInfo.swift +53 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup.swift +103 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup1.swift +111 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup11.swift +66 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup12.swift +75 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup14.swift +37 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup15.swift +46 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup2.swift +163 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroup7.swift +46 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/DataGroupId.swift +105 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/NotImplementedDG.swift +16 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/PACEInfo.swift +415 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/SOD.swift +240 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/DataGroups/SecurityInfo.swift +136 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/Errors.swift +148 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/Logging.swift +32 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/Models/FaceImageInfo.swift +161 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/NFCPassportModel.swift +540 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/NFCViewDisplayMessage.swift +60 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/OpenSSLUtils.swift +705 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/PACEHandler.swift +627 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/PassportReader.swift +387 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/Resources/PrivacyInfo.xcprivacy +14 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/ResponseAPDU.swift +25 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/SecureMessaging.swift +301 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/SecureMessagingSessionKeyGenerator.swift +156 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/SimpleASN1DumpParser.swift +173 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/TagReader.swift +374 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/Utils.swift +430 -0
- package/vendor/ios-passport-reader/Sources/NFCPassportReader/X509Wrapper.swift +168 -0
- package/vendor/ios-passport-reader/scripts/README.md +45 -0
- package/vendor/ios-passport-reader/scripts/extract.py +197 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/*
|
|
2
|
+
See LICENSE folder for this sample’s licensing information.
|
|
3
|
+
|
|
4
|
+
Abstract:
|
|
5
|
+
Main view controller: handles camera, preview and cutout UI.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import UIKit
|
|
9
|
+
import AVFoundation
|
|
10
|
+
import Vision
|
|
11
|
+
|
|
12
|
+
public class ViewController: UIViewController {
|
|
13
|
+
// MARK: - UI objects
|
|
14
|
+
var previewView: PreviewView!
|
|
15
|
+
var cutoutView: UIView!
|
|
16
|
+
var numberView: UILabel!
|
|
17
|
+
|
|
18
|
+
var maskLayer = CAShapeLayer()
|
|
19
|
+
// Device orientation. Updated whenever the orientation changes to a
|
|
20
|
+
// different supported orientation.
|
|
21
|
+
var currentOrientation = UIDeviceOrientation.portrait
|
|
22
|
+
|
|
23
|
+
// MARK: - Capture related objects
|
|
24
|
+
private let captureSession = AVCaptureSession()
|
|
25
|
+
let captureSessionQueue = DispatchQueue(label: "com.example.apple-samplecode.CaptureSessionQueue")
|
|
26
|
+
|
|
27
|
+
var captureDevice: AVCaptureDevice?
|
|
28
|
+
|
|
29
|
+
var videoDataOutput = AVCaptureVideoDataOutput()
|
|
30
|
+
let videoDataOutputQueue = DispatchQueue(label: "com.example.apple-samplecode.VideoDataOutputQueue")
|
|
31
|
+
|
|
32
|
+
// MARK: - Region of interest (ROI) and text orientation
|
|
33
|
+
// Region of video data output buffer that recognition should be run on.
|
|
34
|
+
// Gets recalculated once the bounds of the preview layer are known.
|
|
35
|
+
var regionOfInterest = CGRect(x: 0, y: 0, width: 1, height: 1)
|
|
36
|
+
// Orientation of text to search for in the region of interest.
|
|
37
|
+
var textOrientation = CGImagePropertyOrientation.up
|
|
38
|
+
|
|
39
|
+
// MARK: - Coordinate transforms
|
|
40
|
+
var bufferAspectRatio: Double!
|
|
41
|
+
// Transform from UI orientation to buffer orientation.
|
|
42
|
+
var uiRotationTransform = CGAffineTransform.identity
|
|
43
|
+
// Transform bottom-left coordinates to top-left.
|
|
44
|
+
var bottomToTopTransform = CGAffineTransform(scaleX: 1, y: -1).translatedBy(x: 0, y: -1)
|
|
45
|
+
// Transform coordinates in ROI to global coordinates (still normalized).
|
|
46
|
+
var roiToGlobalTransform = CGAffineTransform.identity
|
|
47
|
+
|
|
48
|
+
// Vision -> AVF coordinate transform.
|
|
49
|
+
var visionToAVFTransform = CGAffineTransform.identity
|
|
50
|
+
|
|
51
|
+
// MARK: - View controller methods
|
|
52
|
+
|
|
53
|
+
public override func viewDidLoad() {
|
|
54
|
+
super.viewDidLoad()
|
|
55
|
+
|
|
56
|
+
// Create views
|
|
57
|
+
previewView = PreviewView()
|
|
58
|
+
cutoutView = UIView()
|
|
59
|
+
numberView = UILabel()
|
|
60
|
+
previewView.translatesAutoresizingMaskIntoConstraints = false
|
|
61
|
+
cutoutView.translatesAutoresizingMaskIntoConstraints = false
|
|
62
|
+
numberView.translatesAutoresizingMaskIntoConstraints = false
|
|
63
|
+
|
|
64
|
+
self.view.addSubview(previewView)
|
|
65
|
+
self.view.addSubview(cutoutView)
|
|
66
|
+
self.view.addSubview(numberView)
|
|
67
|
+
previewView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
|
|
68
|
+
previewView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
|
|
69
|
+
previewView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
|
|
70
|
+
previewView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
|
|
71
|
+
|
|
72
|
+
cutoutView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
|
|
73
|
+
cutoutView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
|
|
74
|
+
cutoutView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
|
|
75
|
+
cutoutView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
|
|
76
|
+
|
|
77
|
+
numberView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
|
|
78
|
+
numberView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
|
|
79
|
+
|
|
80
|
+
let tgr = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
|
|
81
|
+
self.view.addGestureRecognizer(tgr)
|
|
82
|
+
tgr.cancelsTouchesInView = true
|
|
83
|
+
tgr.delaysTouchesEnded = true
|
|
84
|
+
tgr.requiresExclusiveTouchType = true
|
|
85
|
+
|
|
86
|
+
// Set up preview view.
|
|
87
|
+
previewView.session = captureSession
|
|
88
|
+
|
|
89
|
+
// Set up cutout view.
|
|
90
|
+
cutoutView.backgroundColor = UIColor.gray.withAlphaComponent(0.5)
|
|
91
|
+
maskLayer.backgroundColor = UIColor.clear.cgColor
|
|
92
|
+
maskLayer.fillRule = .evenOdd
|
|
93
|
+
cutoutView.layer.mask = maskLayer
|
|
94
|
+
|
|
95
|
+
// Starting the capture session is a blocking call. Perform setup using
|
|
96
|
+
// a dedicated serial dispatch queue to prevent blocking the main thread.
|
|
97
|
+
captureSessionQueue.async {
|
|
98
|
+
self.setupCamera()
|
|
99
|
+
|
|
100
|
+
// Calculate region of interest now that the camera is setup.
|
|
101
|
+
DispatchQueue.main.async {
|
|
102
|
+
// Figure out initial ROI.
|
|
103
|
+
self.calculateRegionOfInterest()
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
|
|
109
|
+
super.viewWillTransition(to: size, with: coordinator)
|
|
110
|
+
|
|
111
|
+
// Only change the current orientation if the new one is landscape or
|
|
112
|
+
// portrait. You can't really do anything about flat or unknown.
|
|
113
|
+
let deviceOrientation = UIDevice.current.orientation
|
|
114
|
+
if deviceOrientation.isPortrait || deviceOrientation.isLandscape {
|
|
115
|
+
currentOrientation = deviceOrientation
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Handle device orientation in the preview layer.
|
|
119
|
+
if let videoPreviewLayerConnection = previewView.videoPreviewLayer.connection {
|
|
120
|
+
if let newVideoOrientation = AVCaptureVideoOrientation(deviceOrientation: deviceOrientation) {
|
|
121
|
+
videoPreviewLayerConnection.videoOrientation = newVideoOrientation
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Orientation changed: figure out new region of interest (ROI).
|
|
126
|
+
calculateRegionOfInterest()
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
public override func viewDidLayoutSubviews() {
|
|
130
|
+
super.viewDidLayoutSubviews()
|
|
131
|
+
updateCutout()
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// MARK: - Setup
|
|
135
|
+
|
|
136
|
+
func calculateRegionOfInterest() {
|
|
137
|
+
// In landscape orientation the desired ROI is specified as the ratio of
|
|
138
|
+
// buffer width to height. When the UI is rotated to portrait, keep the
|
|
139
|
+
// vertical size the same (in buffer pixels). Also try to keep the
|
|
140
|
+
// horizontal size the same up to a maximum ratio.
|
|
141
|
+
let desiredHeightRatio = 0.2
|
|
142
|
+
let desiredWidthRatio = 0.8
|
|
143
|
+
let maxPortraitWidth = 0.9
|
|
144
|
+
// Figure out size of ROI.
|
|
145
|
+
let size: CGSize
|
|
146
|
+
if currentOrientation.isPortrait || currentOrientation == .unknown {
|
|
147
|
+
size = CGSize(width: min(desiredWidthRatio * bufferAspectRatio, maxPortraitWidth), height: desiredHeightRatio / bufferAspectRatio)
|
|
148
|
+
} else {
|
|
149
|
+
size = CGSize(width: desiredWidthRatio, height: desiredHeightRatio)
|
|
150
|
+
}
|
|
151
|
+
// Make it centered.
|
|
152
|
+
regionOfInterest.origin = CGPoint(x: (1 - size.width) / 2, y: (1 - size.height) / 2)
|
|
153
|
+
regionOfInterest.size = size
|
|
154
|
+
|
|
155
|
+
// ROI changed, update transform.
|
|
156
|
+
setupOrientationAndTransform()
|
|
157
|
+
|
|
158
|
+
// Update the cutout to match the new ROI.
|
|
159
|
+
DispatchQueue.main.async {
|
|
160
|
+
// Wait for the next run cycle before updating the cutout. This
|
|
161
|
+
// ensures that the preview layer already has its new orientation.
|
|
162
|
+
self.updateCutout()
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
func updateCutout() {
|
|
167
|
+
// Figure out where the cutout ends up in layer coordinates.
|
|
168
|
+
let roiRectTransform = bottomToTopTransform.concatenating(uiRotationTransform)
|
|
169
|
+
let cutout = previewView.videoPreviewLayer.layerRectConverted(fromMetadataOutputRect: regionOfInterest.applying(roiRectTransform))
|
|
170
|
+
|
|
171
|
+
// Create the mask.
|
|
172
|
+
let path = UIBezierPath(rect: cutoutView.frame)
|
|
173
|
+
path.append(UIBezierPath(rect: cutout))
|
|
174
|
+
maskLayer.path = path.cgPath
|
|
175
|
+
|
|
176
|
+
// Move the number view down to under cutout.
|
|
177
|
+
var numFrame = cutout
|
|
178
|
+
numFrame.origin.y += numFrame.size.height
|
|
179
|
+
numberView.frame = numFrame
|
|
180
|
+
numberView.numberOfLines = 3
|
|
181
|
+
numberView.font = numberView.font.withSize(9)
|
|
182
|
+
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
func setupOrientationAndTransform() {
|
|
186
|
+
// Recalculate the affine transform between Vision coordinates and AVF coordinates.
|
|
187
|
+
|
|
188
|
+
// Compensate for region of interest.
|
|
189
|
+
let roi = regionOfInterest
|
|
190
|
+
roiToGlobalTransform = CGAffineTransform(translationX: roi.origin.x, y: roi.origin.y).scaledBy(x: roi.width, y: roi.height)
|
|
191
|
+
|
|
192
|
+
// Compensate for orientation (buffers always come in the same orientation).
|
|
193
|
+
switch currentOrientation {
|
|
194
|
+
case .landscapeLeft:
|
|
195
|
+
textOrientation = CGImagePropertyOrientation.up
|
|
196
|
+
uiRotationTransform = CGAffineTransform.identity
|
|
197
|
+
case .landscapeRight:
|
|
198
|
+
textOrientation = CGImagePropertyOrientation.down
|
|
199
|
+
uiRotationTransform = CGAffineTransform(translationX: 1, y: 1).rotated(by: CGFloat.pi)
|
|
200
|
+
case .portraitUpsideDown:
|
|
201
|
+
textOrientation = CGImagePropertyOrientation.left
|
|
202
|
+
uiRotationTransform = CGAffineTransform(translationX: 1, y: 0).rotated(by: CGFloat.pi / 2)
|
|
203
|
+
default: // We default everything else to .portraitUp
|
|
204
|
+
textOrientation = CGImagePropertyOrientation.right
|
|
205
|
+
uiRotationTransform = CGAffineTransform(translationX: 0, y: 1).rotated(by: -CGFloat.pi / 2)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Full Vision ROI to AVF transform.
|
|
209
|
+
visionToAVFTransform = roiToGlobalTransform.concatenating(bottomToTopTransform).concatenating(uiRotationTransform)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
func setupCamera() {
|
|
213
|
+
guard let captureDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .back) else {
|
|
214
|
+
print("Could not create capture device.")
|
|
215
|
+
return
|
|
216
|
+
}
|
|
217
|
+
self.captureDevice = captureDevice
|
|
218
|
+
|
|
219
|
+
// NOTE:
|
|
220
|
+
// Requesting 4k buffers allows recognition of smaller text but will
|
|
221
|
+
// consume more power. Use the smallest buffer size necessary to keep
|
|
222
|
+
// down battery usage.
|
|
223
|
+
if captureDevice.supportsSessionPreset(.hd4K3840x2160) {
|
|
224
|
+
captureSession.sessionPreset = AVCaptureSession.Preset.hd4K3840x2160
|
|
225
|
+
bufferAspectRatio = 3840.0 / 2160.0
|
|
226
|
+
} else {
|
|
227
|
+
captureSession.sessionPreset = AVCaptureSession.Preset.hd1920x1080
|
|
228
|
+
bufferAspectRatio = 1920.0 / 1080.0
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
guard let deviceInput = try? AVCaptureDeviceInput(device: captureDevice) else {
|
|
232
|
+
print("Could not create device input.")
|
|
233
|
+
return
|
|
234
|
+
}
|
|
235
|
+
if captureSession.canAddInput(deviceInput) {
|
|
236
|
+
captureSession.addInput(deviceInput)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Configure video data output.
|
|
240
|
+
videoDataOutput.alwaysDiscardsLateVideoFrames = true
|
|
241
|
+
videoDataOutput.setSampleBufferDelegate(self, queue: videoDataOutputQueue)
|
|
242
|
+
videoDataOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_420YpCbCr8BiPlanarFullRange]
|
|
243
|
+
if captureSession.canAddOutput(videoDataOutput) {
|
|
244
|
+
captureSession.addOutput(videoDataOutput)
|
|
245
|
+
// NOTE:
|
|
246
|
+
// There is a trade-off to be made here. Enabling stabilization will
|
|
247
|
+
// give temporally more stable results and should help the recognizer
|
|
248
|
+
// converge. But if it's enabled the VideoDataOutput buffers don't
|
|
249
|
+
// match what's displayed on screen, which makes drawing bounding
|
|
250
|
+
// boxes very hard. Disable it in this app to allow drawing detected
|
|
251
|
+
// bounding boxes on screen.
|
|
252
|
+
videoDataOutput.connection(with: AVMediaType.video)?.preferredVideoStabilizationMode = .off
|
|
253
|
+
} else {
|
|
254
|
+
print("Could not add VDO output")
|
|
255
|
+
return
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Set zoom and autofocus to help focus on very small text.
|
|
259
|
+
do {
|
|
260
|
+
try captureDevice.lockForConfiguration()
|
|
261
|
+
captureDevice.videoZoomFactor = 1.5
|
|
262
|
+
captureDevice.autoFocusRangeRestriction = .near
|
|
263
|
+
captureDevice.unlockForConfiguration()
|
|
264
|
+
} catch {
|
|
265
|
+
print("Could not set zoom level due to error: \(error)")
|
|
266
|
+
return
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
captureSession.startRunning()
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// MARK: - UI drawing and interaction
|
|
273
|
+
|
|
274
|
+
func showString(string: String) {
|
|
275
|
+
// Found a definite number.
|
|
276
|
+
// Stop the camera synchronously to ensure that no further buffers are
|
|
277
|
+
// received. Then update the number view asynchronously.
|
|
278
|
+
captureSessionQueue.sync {
|
|
279
|
+
self.captureSession.stopRunning()
|
|
280
|
+
DispatchQueue.main.async {
|
|
281
|
+
self.numberView.text = string
|
|
282
|
+
self.numberView.isHidden = false
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
@IBAction func handleTap(_ sender: UITapGestureRecognizer) {
|
|
288
|
+
captureSessionQueue.async {
|
|
289
|
+
if !self.captureSession.isRunning {
|
|
290
|
+
self.captureSession.startRunning()
|
|
291
|
+
}
|
|
292
|
+
DispatchQueue.main.async {
|
|
293
|
+
self.numberView.isHidden = true
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// MARK: - AVCaptureVideoDataOutputSampleBufferDelegate
|
|
300
|
+
|
|
301
|
+
extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate {
|
|
302
|
+
|
|
303
|
+
public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
|
|
304
|
+
// This is implemented in VisionViewController.
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// MARK: - Utility extensions
|
|
309
|
+
|
|
310
|
+
extension AVCaptureVideoOrientation {
|
|
311
|
+
init?(deviceOrientation: UIDeviceOrientation) {
|
|
312
|
+
switch deviceOrientation {
|
|
313
|
+
case .portrait: self = .portrait
|
|
314
|
+
case .portraitUpsideDown: self = .portraitUpsideDown
|
|
315
|
+
case .landscapeLeft: self = .landscapeRight
|
|
316
|
+
case .landscapeRight: self = .landscapeLeft
|
|
317
|
+
default: return nil
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/*
|
|
2
|
+
See LICENSE folder for this sample’s licensing information.
|
|
3
|
+
|
|
4
|
+
Abstract:
|
|
5
|
+
Vision view controller.
|
|
6
|
+
Recognizes text using a Vision VNRecognizeTextRequest request handler in pixel buffers from an AVCaptureOutput.
|
|
7
|
+
Displays bounding boxes around recognized text results in real time.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import Foundation
|
|
11
|
+
import UIKit
|
|
12
|
+
import AVFoundation
|
|
13
|
+
import Vision
|
|
14
|
+
import SwiftUI
|
|
15
|
+
|
|
16
|
+
// Wraps the VisionViewController component in a simple UIView that allows a scan of the MRZ area from a Passport/ID Card
|
|
17
|
+
public struct MRZScanner: UIViewControllerRepresentable {
|
|
18
|
+
let completionHandler: (String) -> Void
|
|
19
|
+
|
|
20
|
+
public init(completionHandler: @escaping (String) -> (Void)) {
|
|
21
|
+
self.completionHandler = completionHandler
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public func makeUIViewController(context: Context) -> VisionViewController {
|
|
25
|
+
let vc = VisionViewController()
|
|
26
|
+
|
|
27
|
+
vc.completionHandler = { (mrz) in
|
|
28
|
+
completionHandler( mrz )
|
|
29
|
+
}
|
|
30
|
+
return vc
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public func updateUIViewController(_ uiViewController: VisionViewController, context: Context) {
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
public class VisionViewController: ViewController {
|
|
40
|
+
var request: VNRecognizeTextRequest!
|
|
41
|
+
// Temporal string tracker
|
|
42
|
+
let mrzTracker = StringTracker()
|
|
43
|
+
|
|
44
|
+
var completionHandler: ((String) -> (Void))?
|
|
45
|
+
|
|
46
|
+
public override func viewDidLoad() {
|
|
47
|
+
// Set up vision request before letting ViewController set up the camera
|
|
48
|
+
// so that it exists when the first buffer is received.
|
|
49
|
+
request = VNRecognizeTextRequest(completionHandler: recognizeTextHandler)
|
|
50
|
+
|
|
51
|
+
super.viewDidLoad()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// MARK: - Text recognition
|
|
55
|
+
|
|
56
|
+
// Vision recognition handler.
|
|
57
|
+
func recognizeTextHandler(request: VNRequest, error: Error?) {
|
|
58
|
+
var redBoxes = [CGRect]() // Shows all recognized text lines
|
|
59
|
+
var greenBoxes = [CGRect]() // Shows words that might be serials
|
|
60
|
+
var codes = [String]()
|
|
61
|
+
|
|
62
|
+
guard let results = request.results as? [VNRecognizedTextObservation] else {
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let maximumCandidates = 1
|
|
67
|
+
for visionResult in results {
|
|
68
|
+
guard let candidate = visionResult.topCandidates(maximumCandidates).first else { continue }
|
|
69
|
+
|
|
70
|
+
var numberIsSubstring = true
|
|
71
|
+
|
|
72
|
+
// Remove spaces from candidate.string - improves recognition vastly
|
|
73
|
+
let mrz = candidate.string.replacingOccurrences(of: " ", with: "")
|
|
74
|
+
|
|
75
|
+
if let result = candidate.string.checkMrz() {
|
|
76
|
+
if(result != "nil"){
|
|
77
|
+
codes.append(result)
|
|
78
|
+
numberIsSubstring = false
|
|
79
|
+
|
|
80
|
+
greenBoxes.append(visionResult.boundingBox)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if numberIsSubstring {
|
|
85
|
+
redBoxes.append(visionResult.boundingBox)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Log any found numbers.
|
|
90
|
+
mrzTracker.logFrame(strings: codes)
|
|
91
|
+
show(boxGroups: [(color: UIColor.red.cgColor, boxes: redBoxes), (color: UIColor.green.cgColor, boxes: greenBoxes)])
|
|
92
|
+
|
|
93
|
+
// Check if we have any temporally stable numbers.
|
|
94
|
+
if let sureNumber = mrzTracker.getStableString() {
|
|
95
|
+
showString(string: sureNumber)
|
|
96
|
+
mrzTracker.reset(string: sureNumber)
|
|
97
|
+
|
|
98
|
+
DispatchQueue.main.async {
|
|
99
|
+
self.completionHandler?(sureNumber)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public override func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
|
|
106
|
+
if let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
|
|
107
|
+
// Configure for running in real-time.
|
|
108
|
+
request.recognitionLevel = .fast
|
|
109
|
+
// Language correction won't help recognizing phone numbers. It also
|
|
110
|
+
// makes recognition slower.
|
|
111
|
+
request.usesLanguageCorrection = false
|
|
112
|
+
// Only run on the region of interest for maximum speed.
|
|
113
|
+
request.regionOfInterest = regionOfInterest
|
|
114
|
+
|
|
115
|
+
let requestHandler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: textOrientation, options: [:])
|
|
116
|
+
do {
|
|
117
|
+
try requestHandler.perform([request])
|
|
118
|
+
} catch {
|
|
119
|
+
print(error)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// MARK: - Bounding box drawing
|
|
125
|
+
|
|
126
|
+
// Draw a box on screen. Must be called from main queue.
|
|
127
|
+
var boxLayer = [CAShapeLayer]()
|
|
128
|
+
func draw(rect: CGRect, color: CGColor) {
|
|
129
|
+
let layer = CAShapeLayer()
|
|
130
|
+
layer.opacity = 0.5
|
|
131
|
+
layer.borderColor = color
|
|
132
|
+
layer.borderWidth = 1
|
|
133
|
+
layer.frame = rect
|
|
134
|
+
boxLayer.append(layer)
|
|
135
|
+
previewView.videoPreviewLayer.insertSublayer(layer, at: 1)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Remove all drawn boxes. Must be called on main queue.
|
|
139
|
+
func removeBoxes() {
|
|
140
|
+
for layer in boxLayer {
|
|
141
|
+
layer.removeFromSuperlayer()
|
|
142
|
+
}
|
|
143
|
+
boxLayer.removeAll()
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
typealias ColoredBoxGroup = (color: CGColor, boxes: [CGRect])
|
|
147
|
+
|
|
148
|
+
// Draws groups of colored boxes.
|
|
149
|
+
func show(boxGroups: [ColoredBoxGroup]) {
|
|
150
|
+
DispatchQueue.main.async {
|
|
151
|
+
let layer = self.previewView.videoPreviewLayer
|
|
152
|
+
self.removeBoxes()
|
|
153
|
+
for boxGroup in boxGroups {
|
|
154
|
+
let color = boxGroup.color
|
|
155
|
+
for box in boxGroup.boxes {
|
|
156
|
+
let rect = layer.layerRectConverted(fromMetadataOutputRect: box.applying(self.visionToAVFTransform))
|
|
157
|
+
self.draw(rect: rect, color: color)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>com.apple.developer.nfc.readersession.formats</key>
|
|
6
|
+
<array>
|
|
7
|
+
<string>TAG</string>
|
|
8
|
+
</array>
|
|
9
|
+
</dict>
|
|
10
|
+
</plist>
|
package/vendor/ios-passport-reader/Examples/Example_SPM/NFCPassportReaderApp/SceneDelegate.swift
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
//
|
|
2
|
+
// SceneDelegate.swift
|
|
3
|
+
// NFCPassportReaderApp
|
|
4
|
+
//
|
|
5
|
+
// Created by Andy Qua on 06/06/2019.
|
|
6
|
+
// Copyright © 2019 Andy Qua. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import UIKit
|
|
10
|
+
import SwiftUI
|
|
11
|
+
|
|
12
|
+
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|
13
|
+
|
|
14
|
+
var window: UIWindow?
|
|
15
|
+
// var settings = SettingsStore()
|
|
16
|
+
var settings = SettingsStoreCAN()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
|
20
|
+
|
|
21
|
+
// Use a UIHostingController as window root view controller
|
|
22
|
+
if let windowScene = scene as? UIWindowScene {
|
|
23
|
+
let window = UIWindow(windowScene: windowScene)
|
|
24
|
+
window.rootViewController = UIHostingController(rootView: CanKeyView().environmentObject(settings))
|
|
25
|
+
self.window = window
|
|
26
|
+
window.makeKeyAndVisible()
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
func sceneDidDisconnect(_ scene: UIScene) {
|
|
31
|
+
// Called as the scene is being released by the system.
|
|
32
|
+
// This occurs shortly after the scene enters the background, or when its session is discarded.
|
|
33
|
+
// Release any resources associated with this scene that can be re-created the next time the scene connects.
|
|
34
|
+
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
func sceneDidBecomeActive(_ scene: UIScene) {
|
|
38
|
+
// Called when the scene has moved from an inactive state to an active state.
|
|
39
|
+
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func sceneWillResignActive(_ scene: UIScene) {
|
|
43
|
+
// Called when the scene will move from an active state to an inactive state.
|
|
44
|
+
// This may occur due to temporary interruptions (ex. an incoming phone call).
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
func sceneWillEnterForeground(_ scene: UIScene) {
|
|
48
|
+
// Called as the scene transitions from the background to the foreground.
|
|
49
|
+
// Use this method to undo the changes made on entering the background.
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
func sceneDidEnterBackground(_ scene: UIScene) {
|
|
53
|
+
// Called as the scene transitions from the foreground to the background.
|
|
54
|
+
// Use this method to save data, release shared resources, and store enough scene-specific state information
|
|
55
|
+
// to restore the scene back to its current state.
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|