From 83b427488de7e46115fc73a194bc787dbc7a4985 Mon Sep 17 00:00:00 2001 From: Vlad Suhomlinov Date: Sat, 24 Apr 2021 11:39:17 +0300 Subject: [PATCH] Add scanner test --- .gitignore | 1 + build-scripts | 2 +- testapp.xcodeproj/project.pbxproj | 123 +++++++++++++- .../xcshareddata/swiftpm/Package.resolved | 52 ++++++ testapp/Assets.xcassets/Contents.json | 6 +- .../corners.imageset/Contents.json | 15 ++ .../corners.imageset/corners.pdf | 155 ++++++++++++++++++ .../light-disable.imageset/Contents.json | 15 ++ .../light-disable.imageset/light-disable.pdf | 107 ++++++++++++ .../lightning.imageset/Contents.json | 15 ++ .../lightning.imageset/lightning.pdf | 91 ++++++++++ testapp/CardScanner.swift | 107 ++++++++++++ testapp/Images.swift | 24 +++ testapp/Info.plist | 2 + testapp/Resources/GoogleService-Info.plist | 16 +- testapp/ViewController.swift | 116 ++++++++++++- 16 files changed, 828 insertions(+), 19 deletions(-) create mode 100644 testapp.xcworkspace/xcshareddata/swiftpm/Package.resolved create mode 100644 testapp/Assets.xcassets/corners.imageset/Contents.json create mode 100644 testapp/Assets.xcassets/corners.imageset/corners.pdf create mode 100644 testapp/Assets.xcassets/light-disable.imageset/Contents.json create mode 100644 testapp/Assets.xcassets/light-disable.imageset/light-disable.pdf create mode 100644 testapp/Assets.xcassets/lightning.imageset/Contents.json create mode 100644 testapp/Assets.xcassets/lightning.imageset/lightning.pdf create mode 100644 testapp/CardScanner.swift create mode 100644 testapp/Images.swift diff --git a/.gitignore b/.gitignore index 1d2be38..6f6b98a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Xcode # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore +.DS_Store ## User settings xcuserdata/ diff --git a/build-scripts b/build-scripts index 54fd9f1..2ac36fb 160000 --- a/build-scripts +++ b/build-scripts @@ -1 +1 @@ -Subproject commit 54fd9f11068bf9264e29ccd77827c5bda961d37c +Subproject commit 2ac36fbc1b190b229d906d28ba23390f55fab335 diff --git a/testapp.xcodeproj/project.pbxproj b/testapp.xcodeproj/project.pbxproj index 4e903c2..861e55c 100644 --- a/testapp.xcodeproj/project.pbxproj +++ b/testapp.xcodeproj/project.pbxproj @@ -3,23 +3,35 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ 3400B87893AA2CBDF5E3FB8C /* Pods_testapp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7CEF4CC413320F5A9AC9F4AD /* Pods_testapp.framework */; }; + 4C520A242633FE7D004C4424 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4C520A232633FE7D004C4424 /* GoogleService-Info.plist */; }; + 4C520A292633FF33004C4424 /* QRCodeReader in Frameworks */ = {isa = PBXBuildFile; productRef = 4C520A282633FF33004C4424 /* QRCodeReader */; }; + 4C520A2D2633FFBF004C4424 /* TISwiftUtils in Frameworks */ = {isa = PBXBuildFile; productRef = 4C520A2C2633FFBF004C4424 /* TISwiftUtils */; }; + 4C520A2F2633FFBF004C4424 /* TIUIKitCore in Frameworks */ = {isa = PBXBuildFile; productRef = 4C520A2E2633FFBF004C4424 /* TIUIKitCore */; }; + 4C520A312633FFBF004C4424 /* TIFoundationUtils in Frameworks */ = {isa = PBXBuildFile; productRef = 4C520A302633FFBF004C4424 /* TIFoundationUtils */; }; + 4C520A332633FFBF004C4424 /* TIUIElements in Frameworks */ = {isa = PBXBuildFile; productRef = 4C520A322633FFBF004C4424 /* TIUIElements */; }; + 4C520A362633FFE1004C4424 /* CardScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C520A352633FFE1004C4424 /* CardScanner.swift */; }; + 4C520A3B2634007D004C4424 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 4C520A3A2634007D004C4424 /* SnapKit */; }; + 4C520A3E263401A9004C4424 /* Images.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C520A3D263401A9004C4424 /* Images.swift */; }; + 4C520A4726340555004C4424 /* Reg in Frameworks */ = {isa = PBXBuildFile; productRef = 4C520A4626340555004C4424 /* Reg */; }; 4CEDA81A243116E2009937F6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEDA819243116E2009937F6 /* AppDelegate.swift */; }; 4CEDA81C243116E2009937F6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEDA81B243116E2009937F6 /* SceneDelegate.swift */; }; 4CEDA81E243116E2009937F6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEDA81D243116E2009937F6 /* ViewController.swift */; }; 4CEDA821243116E2009937F6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4CEDA81F243116E2009937F6 /* Main.storyboard */; }; 4CEDA823243116E4009937F6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4CEDA822243116E4009937F6 /* Assets.xcassets */; }; 4CEDA826243116E4009937F6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4CEDA824243116E4009937F6 /* LaunchScreen.storyboard */; }; - 4CEDA82E24311BB7009937F6 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4CEDA82D24311BB7009937F6 /* GoogleService-Info.plist */; }; 4CEDA83224311D39009937F6 /* FirebaseConfigurator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEDA83124311D39009937F6 /* FirebaseConfigurator.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 1A298113541BC1F2C4C002E5 /* Pods-testapp.appstore.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testapp.appstore.xcconfig"; path = "Target Support Files/Pods-testapp/Pods-testapp.appstore.xcconfig"; sourceTree = ""; }; + 4C520A232633FE7D004C4424 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 4C520A352633FFE1004C4424 /* CardScanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardScanner.swift; sourceTree = ""; }; + 4C520A3D263401A9004C4424 /* Images.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Images.swift; sourceTree = ""; }; 4CEDA816243116E2009937F6 /* testapp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testapp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4CEDA819243116E2009937F6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 4CEDA81B243116E2009937F6 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -28,7 +40,6 @@ 4CEDA822243116E4009937F6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 4CEDA825243116E4009937F6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 4CEDA827243116E4009937F6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 4CEDA82D24311BB7009937F6 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 4CEDA83124311D39009937F6 /* FirebaseConfigurator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirebaseConfigurator.swift; sourceTree = ""; }; 78341F7625BEA2BE0045D4D3 /* AppStore.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AppStore.entitlements; sourceTree = ""; }; 78341F7725BEA2BE0045D4D3 /* Enterprise.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Enterprise.entitlements; sourceTree = ""; }; @@ -62,7 +73,14 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4C520A2D2633FFBF004C4424 /* TISwiftUtils in Frameworks */, + 4C520A4726340555004C4424 /* Reg in Frameworks */, 3400B87893AA2CBDF5E3FB8C /* Pods_testapp.framework in Frameworks */, + 4C520A312633FFBF004C4424 /* TIFoundationUtils in Frameworks */, + 4C520A3B2634007D004C4424 /* SnapKit in Frameworks */, + 4C520A292633FF33004C4424 /* QRCodeReader in Frameworks */, + 4C520A332633FFBF004C4424 /* TIUIElements in Frameworks */, + 4C520A2F2633FFBF004C4424 /* TIUIKitCore in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -103,6 +121,8 @@ 78341F7625BEA2BE0045D4D3 /* AppStore.entitlements */, 78341F7725BEA2BE0045D4D3 /* Enterprise.entitlements */, 78341F7825BEA2BE0045D4D3 /* Standard.entitlements */, + 4C520A352633FFE1004C4424 /* CardScanner.swift */, + 4C520A3D263401A9004C4424 /* Images.swift */, ); path = testapp; sourceTree = ""; @@ -110,7 +130,7 @@ 4CEDA82F24311BC0009937F6 /* Resources */ = { isa = PBXGroup; children = ( - 4CEDA82D24311BB7009937F6 /* GoogleService-Info.plist */, + 4C520A232633FE7D004C4424 /* GoogleService-Info.plist */, ); path = Resources; sourceTree = ""; @@ -177,6 +197,15 @@ dependencies = ( ); name = testapp; + packageProductDependencies = ( + 4C520A282633FF33004C4424 /* QRCodeReader */, + 4C520A2C2633FFBF004C4424 /* TISwiftUtils */, + 4C520A2E2633FFBF004C4424 /* TIUIKitCore */, + 4C520A302633FFBF004C4424 /* TIFoundationUtils */, + 4C520A322633FFBF004C4424 /* TIUIElements */, + 4C520A3A2634007D004C4424 /* SnapKit */, + 4C520A4626340555004C4424 /* Reg */, + ); productName = testapp; productReference = 4CEDA816243116E2009937F6 /* testapp.app */; productType = "com.apple.product-type.application"; @@ -205,6 +234,12 @@ Base, ); mainGroup = 4CEDA80D243116E1009937F6; + packageReferences = ( + 4C520A272633FF33004C4424 /* XCRemoteSwiftPackageReference "QRCodeReader-ios" */, + 4C520A2B2633FFBF004C4424 /* XCRemoteSwiftPackageReference "LeadKit" */, + 4C520A392634007D004C4424 /* XCRemoteSwiftPackageReference "SnapKit" */, + 4C520A4526340555004C4424 /* XCRemoteSwiftPackageReference "Reg" */, + ); productRefGroup = 4CEDA817243116E2009937F6 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -220,9 +255,9 @@ buildActionMask = 2147483647; files = ( 4CEDA826243116E4009937F6 /* LaunchScreen.storyboard in Resources */, - 4CEDA82E24311BB7009937F6 /* GoogleService-Info.plist in Resources */, 4CEDA823243116E4009937F6 /* Assets.xcassets in Resources */, 4CEDA821243116E2009937F6 /* Main.storyboard in Resources */, + 4C520A242633FE7D004C4424 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -276,9 +311,11 @@ buildActionMask = 2147483647; files = ( 4CEDA81E243116E2009937F6 /* ViewController.swift in Sources */, + 4C520A3E263401A9004C4424 /* Images.swift in Sources */, 4CEDA83224311D39009937F6 /* FirebaseConfigurator.swift in Sources */, 4CEDA81A243116E2009937F6 /* AppDelegate.swift in Sources */, 4CEDA81C243116E2009937F6 /* SceneDelegate.swift in Sources */, + 4C520A362633FFE1004C4424 /* CardScanner.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -426,6 +463,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = testapp/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -442,6 +480,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = testapp/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -513,6 +552,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = testapp/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -547,6 +587,79 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 4C520A272633FF33004C4424 /* XCRemoteSwiftPackageReference "QRCodeReader-ios" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/TouchInstinct/QRCodeReader-ios"; + requirement = { + branch = feature/card_scan; + kind = branch; + }; + }; + 4C520A2B2633FFBF004C4424 /* XCRemoteSwiftPackageReference "LeadKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/TouchInstinct/LeadKit"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.1.1; + }; + }; + 4C520A392634007D004C4424 /* XCRemoteSwiftPackageReference "SnapKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/SnapKit/SnapKit"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.0.1; + }; + }; + 4C520A4526340555004C4424 /* XCRemoteSwiftPackageReference "Reg" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/yhkaplan/Reg.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.3.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 4C520A282633FF33004C4424 /* QRCodeReader */ = { + isa = XCSwiftPackageProductDependency; + package = 4C520A272633FF33004C4424 /* XCRemoteSwiftPackageReference "QRCodeReader-ios" */; + productName = QRCodeReader; + }; + 4C520A2C2633FFBF004C4424 /* TISwiftUtils */ = { + isa = XCSwiftPackageProductDependency; + package = 4C520A2B2633FFBF004C4424 /* XCRemoteSwiftPackageReference "LeadKit" */; + productName = TISwiftUtils; + }; + 4C520A2E2633FFBF004C4424 /* TIUIKitCore */ = { + isa = XCSwiftPackageProductDependency; + package = 4C520A2B2633FFBF004C4424 /* XCRemoteSwiftPackageReference "LeadKit" */; + productName = TIUIKitCore; + }; + 4C520A302633FFBF004C4424 /* TIFoundationUtils */ = { + isa = XCSwiftPackageProductDependency; + package = 4C520A2B2633FFBF004C4424 /* XCRemoteSwiftPackageReference "LeadKit" */; + productName = TIFoundationUtils; + }; + 4C520A322633FFBF004C4424 /* TIUIElements */ = { + isa = XCSwiftPackageProductDependency; + package = 4C520A2B2633FFBF004C4424 /* XCRemoteSwiftPackageReference "LeadKit" */; + productName = TIUIElements; + }; + 4C520A3A2634007D004C4424 /* SnapKit */ = { + isa = XCSwiftPackageProductDependency; + package = 4C520A392634007D004C4424 /* XCRemoteSwiftPackageReference "SnapKit" */; + productName = SnapKit; + }; + 4C520A4626340555004C4424 /* Reg */ = { + isa = XCSwiftPackageProductDependency; + package = 4C520A4526340555004C4424 /* XCRemoteSwiftPackageReference "Reg" */; + productName = Reg; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 4CEDA80E243116E1009937F6 /* Project object */; } diff --git a/testapp.xcworkspace/xcshareddata/swiftpm/Package.resolved b/testapp.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..4e02e3f --- /dev/null +++ b/testapp.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,52 @@ +{ + "object": { + "pins": [ + { + "package": "LeadKit", + "repositoryURL": "https://github.com/TouchInstinct/LeadKit", + "state": { + "branch": null, + "revision": "e86dcc81f9d5cf802ea7e1941326f8c24fcb2a15", + "version": "1.1.1" + } + }, + { + "package": "QRCodeReader", + "repositoryURL": "https://github.com/TouchInstinct/QRCodeReader-ios", + "state": { + "branch": "feature/card_scan", + "revision": "ba9d3501198aa0a1d6d369d79ca41c8d4057ab0d", + "version": null + } + }, + { + "package": "Reg", + "repositoryURL": "https://github.com/yhkaplan/Reg.git", + "state": { + "branch": null, + "revision": "c8f1f51bc088708b3b3ecf04523b5bedd6914222", + "version": "0.3.0" + } + }, + { + "package": "SnapKit", + "repositoryURL": "https://github.com/SnapKit/SnapKit", + "state": { + "branch": null, + "revision": "d458564516e5676af9c70b4f4b2a9178294f1bc6", + "version": "5.0.1" + } + }, + { + "package": "TableKit", + "repositoryURL": "https://github.com/maxsokolov/TableKit.git", + "state": { + "branch": null, + "revision": "8bf4840d9d0475a92352f02f368f88b74eced447", + "version": "2.11.0" + } + } + ] + }, + "version": 1 +} diff --git a/testapp/Assets.xcassets/Contents.json b/testapp/Assets.xcassets/Contents.json index da4a164..73c0059 100644 --- a/testapp/Assets.xcassets/Contents.json +++ b/testapp/Assets.xcassets/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/testapp/Assets.xcassets/corners.imageset/Contents.json b/testapp/Assets.xcassets/corners.imageset/Contents.json new file mode 100644 index 0000000..980024e --- /dev/null +++ b/testapp/Assets.xcassets/corners.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "corners.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/testapp/Assets.xcassets/corners.imageset/corners.pdf b/testapp/Assets.xcassets/corners.imageset/corners.pdf new file mode 100644 index 0000000..b64e503 --- /dev/null +++ b/testapp/Assets.xcassets/corners.imageset/corners.pdf @@ -0,0 +1,155 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 300.000000 176.000000 cm +0.917647 0.254902 0.498039 scn +40.000000 43.000000 m +43.000000 43.000000 l +43.000000 46.000000 l +40.000000 46.000000 l +40.000000 43.000000 l +h +0.000000 40.000000 m +40.000000 40.000000 l +40.000000 46.000000 l +0.000000 46.000000 l +0.000000 40.000000 l +h +37.000000 43.000000 m +37.000000 3.000000 l +43.000000 3.000000 l +43.000000 43.000000 l +37.000000 43.000000 l +h +f +n +Q +q +-1.000000 -0.000000 -0.000000 1.000000 43.000000 176.000000 cm +0.917647 0.254902 0.498039 scn +40.000000 43.000000 m +43.000000 43.000000 l +43.000000 46.000000 l +40.000000 46.000000 l +40.000000 43.000000 l +h +0.000000 40.000000 m +40.000000 40.000000 l +40.000000 46.000000 l +0.000000 46.000000 l +0.000000 40.000000 l +h +37.000000 43.000000 m +37.000000 3.000000 l +43.000000 3.000000 l +43.000000 43.000000 l +37.000000 43.000000 l +h +f +n +Q +q +1.000000 0.000000 -0.000000 -1.000000 300.000000 46.000000 cm +0.917647 0.254902 0.498039 scn +40.000000 43.000000 m +43.000000 43.000000 l +43.000000 46.000000 l +40.000000 46.000000 l +40.000000 43.000000 l +h +0.000000 40.000000 m +40.000000 40.000000 l +40.000000 46.000000 l +0.000000 46.000000 l +0.000000 40.000000 l +h +37.000000 43.000000 m +37.000000 3.000000 l +43.000000 3.000000 l +43.000000 43.000000 l +37.000000 43.000000 l +h +f +n +Q +q +-1.000000 -0.000000 -0.000000 -1.000000 43.000000 46.000000 cm +0.917647 0.254902 0.498039 scn +40.000000 43.000000 m +43.000000 43.000000 l +43.000000 46.000000 l +40.000000 46.000000 l +40.000000 43.000000 l +h +0.000000 40.000000 m +40.000000 40.000000 l +40.000000 46.000000 l +0.000000 46.000000 l +0.000000 40.000000 l +h +37.000000 43.000000 m +37.000000 3.000000 l +43.000000 3.000000 l +43.000000 43.000000 l +37.000000 43.000000 l +h +f +n +Q + +endstream +endobj + +3 0 obj + 1758 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 343.000000 222.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Type /Catalog + /Pages 5 0 R + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000001848 00000 n +0000001871 00000 n +0000002046 00000 n +0000002120 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +2179 +%%EOF \ No newline at end of file diff --git a/testapp/Assets.xcassets/light-disable.imageset/Contents.json b/testapp/Assets.xcassets/light-disable.imageset/Contents.json new file mode 100644 index 0000000..a3dabe4 --- /dev/null +++ b/testapp/Assets.xcassets/light-disable.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "light-disable.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/testapp/Assets.xcassets/light-disable.imageset/light-disable.pdf b/testapp/Assets.xcassets/light-disable.imageset/light-disable.pdf new file mode 100644 index 0000000..7d18ccd --- /dev/null +++ b/testapp/Assets.xcassets/light-disable.imageset/light-disable.pdf @@ -0,0 +1,107 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 5.511230 1.697998 cm +1.000000 1.000000 1.000000 scn +8.937988 15.096902 m +10.285645 13.739480 l +14.191895 13.739480 l +14.191895 13.680886 l +12.385254 11.346902 l +13.801270 9.930886 l +16.408691 13.280496 l +17.404785 14.550027 16.994629 15.702371 15.598145 15.702371 c +11.164551 15.702371 l +12.199707 22.352762 l +12.404785 23.807840 10.773926 24.325418 9.924316 23.270731 c +5.715332 17.967995 l +7.092285 16.591042 l +9.885254 20.155497 l +9.992676 20.135965 l +8.937988 15.096902 l +h +0.227051 19.452370 m +15.598145 4.091043 l +15.910645 3.788309 16.428223 3.778543 16.730957 4.091043 c +17.043457 4.393778 17.043457 4.911356 16.730957 5.223856 c +1.369629 20.575418 l +1.057129 20.887918 0.529785 20.887918 0.227051 20.575418 c +-0.075684 20.272684 -0.075684 19.755104 0.227051 19.452370 c +h +11.232910 6.688700 m +9.865723 8.065652 l +7.170410 4.667215 l +7.053223 4.686747 l +8.117676 9.735574 l +6.779785 11.083230 l +2.863770 11.083230 l +2.863770 11.141824 l +4.572754 13.348855 l +3.156738 14.774636 l +0.627441 11.542214 l +-0.378418 10.262918 0.041504 9.120339 1.437988 9.120339 c +5.871582 9.120339 l +4.836426 2.469950 l +4.621582 1.014872 6.252441 0.497293 7.111816 1.561747 c +11.232910 6.688700 l +h +f +n +Q + +endstream +endobj + +3 0 obj + 1258 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 28.000000 28.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Type /Catalog + /Pages 5 0 R + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000001348 00000 n +0000001371 00000 n +0000001544 00000 n +0000001618 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +1677 +%%EOF \ No newline at end of file diff --git a/testapp/Assets.xcassets/lightning.imageset/Contents.json b/testapp/Assets.xcassets/lightning.imageset/Contents.json new file mode 100644 index 0000000..c2a1553 --- /dev/null +++ b/testapp/Assets.xcassets/lightning.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "lightning.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/testapp/Assets.xcassets/lightning.imageset/lightning.pdf b/testapp/Assets.xcassets/lightning.imageset/lightning.pdf new file mode 100644 index 0000000..4eb1f44 --- /dev/null +++ b/testapp/Assets.xcassets/lightning.imageset/lightning.pdf @@ -0,0 +1,91 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 0.000000 -1.143311 cm +1.000000 1.000000 1.000000 scn +7.081509 1.780159 m +16.349087 13.459846 l +17.354946 14.719612 16.925259 15.881721 15.538541 15.881721 c +11.095181 15.881721 l +12.130338 22.532112 l +12.335416 23.987190 10.821744 24.651253 9.854947 23.450081 c +0.558072 11.721565 l +-0.457553 10.452034 -0.027866 9.299690 1.368619 9.299690 c +5.811978 9.299690 l +4.776822 2.649300 l +4.571743 1.194221 6.114712 0.578987 7.081509 1.780159 c +h +6.983853 4.856331 m +8.145963 10.647346 l +8.233853 11.008675 8.126431 11.262581 7.716275 11.262581 c +2.784634 11.262581 l +2.784634 11.311409 l +9.815885 20.334846 l +9.933072 20.334846 l +8.761197 14.534065 l +8.673306 14.172737 8.780728 13.918831 9.181119 13.918831 c +14.112760 13.918831 l +14.112760 13.870003 l +7.101040 4.856331 l +6.983853 4.856331 l +h +f +n +Q + +endstream +endobj + +3 0 obj + 863 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 16.900391 22.928955 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Type /Catalog + /Pages 5 0 R + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000000953 00000 n +0000000975 00000 n +0000001148 00000 n +0000001222 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +1281 +%%EOF \ No newline at end of file diff --git a/testapp/CardScanner.swift b/testapp/CardScanner.swift new file mode 100644 index 0000000..8873acd --- /dev/null +++ b/testapp/CardScanner.swift @@ -0,0 +1,107 @@ +// +// CardScanner.swift +// testapp +// +// Created by Vlad Suhomlinov on 24.04.2021. +// Copyright © 2021 touchin. All rights reserved. +// + +import TIUIElements +import QRCodeReader +import UIKit +import SnapKit + +final class CardScanner: BaseInitializableView { + + private let titleLabel = UILabel() + private let qrEdgeIconView = UIImageView(image: .corners) + private let focusView: FocusView = .init(cornerColor: .init(red: 234 / 255, + green: 65 / 255, + blue: 127 / 255, + alpha: 1), + cornerLength: 40, + cornerThickness: 6) + + let scannerView = CardReaderView() + let flashlightButton = UIButton() + + // MARK: - Configurable View + + override func configureAppearance() { + super.configureAppearance() + + backgroundColor = .black + + titleLabel.textColor = .white + titleLabel.textAlignment = .center + titleLabel.numberOfLines = 0 + + updateFlashlightButtonAppearance(isTorchEnabled: false) + + qrEdgeIconView.isHidden = true + } + + override func addViews() { + super.addViews() + + addSubviews(scannerView, titleLabel, flashlightButton) + + qrEdgeIconView.addSubview(focusView) + scannerView.overlay.addSubview(qrEdgeIconView) + + scannerView.overlay.focusView = focusView + } + + override func configureLayout() { + super.configureLayout() + + scannerView.snp.makeConstraints { + $0.edges.equalToSuperview() + } + + qrEdgeIconView.snp.makeConstraints { + $0.center.equalToSuperview() + $0.left.right.equalToSuperview().inset(16) + $0.height.equalTo(qrEdgeIconView.snp.width).multipliedBy(0.64) + } + + focusView.snp.makeConstraints { + $0.edges.equalToSuperview() + } + + titleLabel.snp.makeConstraints { + $0.top.equalTo(qrEdgeIconView.snp.bottom).offset(28) + $0.centerX.equalToSuperview() + $0.left.right.equalToSuperview().inset(32) + } + + flashlightButton.snp.makeConstraints { + $0.top.trailing.equalTo(safeAreaLayoutGuide).inset(16) + $0.size.equalTo(CGFloat.topButtonSize) + } + } + + + func updateFlashlightButtonAppearance(isTorchEnabled: Bool) { + flashlightButton.setImage(isTorchEnabled ? .lightOff : .lightOn, for: .normal) + } + + override func localize() { + super.localize() + + titleLabel.text = "Обязательно проверяйте номер карты после распознавания" + } +} + +// MARK: - Constants + +private extension CGFloat { + static let topButtonSize: CGFloat = 28 +} + +extension FocusView { + + static let empty = FocusView(cornerColor: .clear, + cornerLength: 0, + cornerThickness: 0) +} diff --git a/testapp/Images.swift b/testapp/Images.swift new file mode 100644 index 0000000..9267628 --- /dev/null +++ b/testapp/Images.swift @@ -0,0 +1,24 @@ +// +// Images.swift +// testapp +// +// Created by Vlad Suhomlinov on 24.04.2021. +// Copyright © 2021 touchin. All rights reserved. +// + +import UIKit + +extension UIImage { + + static var lightOn: UIImage { + #imageLiteral(resourceName: "lightning.pdf") + } + + static var lightOff: UIImage { + #imageLiteral(resourceName: "light-disable") + } + + static var corners: UIImage { + #imageLiteral(resourceName: "corners") + } +} diff --git a/testapp/Info.plist b/testapp/Info.plist index acb5a99..3a9dfa8 100644 --- a/testapp/Info.plist +++ b/testapp/Info.plist @@ -2,6 +2,8 @@ + NSCameraUsageDescription + Ну пожалуйста CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable diff --git a/testapp/Resources/GoogleService-Info.plist b/testapp/Resources/GoogleService-Info.plist index b80f8d5..a126e1d 100644 --- a/testapp/Resources/GoogleService-Info.plist +++ b/testapp/Resources/GoogleService-Info.plist @@ -3,21 +3,21 @@ CLIENT_ID - 1009875821676-2s1d4tjn9dojsp3ao31cicm174mjehc5.apps.googleusercontent.com + 1084813714260-7qto2ituvflo73h8r2fttf0u6s0nc27h.apps.googleusercontent.com REVERSED_CLIENT_ID - com.googleusercontent.apps.1009875821676-2s1d4tjn9dojsp3ao31cicm174mjehc5 + com.googleusercontent.apps.1084813714260-7qto2ituvflo73h8r2fttf0u6s0nc27h API_KEY - AIzaSyDSUnGsmBO5kvfTeVDJywsyigcqqWSmuzY + AIzaSyBoYUwnZcWY_mxIAO1cxyrKlbW2ta67cQ8 GCM_SENDER_ID - 1009875821676 + 1084813714260 PLIST_VERSION 1 BUNDLE_ID ru.touchin.testapp PROJECT_ID - ti-testapp + testproject-ac7fe STORAGE_BUCKET - ti-testapp.appspot.com + testproject-ac7fe.appspot.com IS_ADS_ENABLED IS_ANALYTICS_ENABLED @@ -29,8 +29,8 @@ IS_SIGNIN_ENABLED GOOGLE_APP_ID - 1:1009875821676:ios:3b95cafada68fd3a07a449 + 1:1084813714260:ios:096f9bb10bb971c6255ec1 DATABASE_URL - https://ti-testapp.firebaseio.com + https://testproject-ac7fe.firebaseio.com \ No newline at end of file diff --git a/testapp/ViewController.swift b/testapp/ViewController.swift index a1e0a66..050decb 100644 --- a/testapp/ViewController.swift +++ b/testapp/ViewController.swift @@ -7,15 +7,127 @@ // import UIKit +import QRCodeReader +import Reg +import SnapKit class ViewController: UIViewController { + let cardScanner = CardReader(factory: CardFactoryImpl(), onUpdateRectOfInterest: nil) + let cardScannerView = CardScanner() + override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view. + + view.addSubview(cardScannerView) + + cardScanner.stopScanningWhenCodeIsFound = true + + cardScannerView.scannerView.setReader(cardScanner) + + cardScannerView.snp.makeConstraints { + $0.edges.equalToSuperview() + } + + cardScanner.didFind = { [weak self] in + self?.handleResult(card: $0) + } + + cardScannerView.flashlightButton.addTarget(self, action: #selector(toggleFlashlightAction), for: .touchUpInside) } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + cardScanner.startScanning() + + cardScannerView.layoutSubviews() + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + + cardScanner.stopScanning() + } + + @objc private func toggleFlashlightAction() { - + cardScanner.isTorchEnabled.toggle() + cardScannerView.updateFlashlightButtonAppearance(isTorchEnabled: cardScanner.isTorchEnabled) + } + + private func handleResult(card: Card) { + + let alert = UIAlertController(title: "Номер карты", message: card.number, preferredStyle: .alert) + let actionTrue = UIAlertAction(title: "Верно", style: .default, handler: { [weak self] _ in + self?.cardScanner.startScanning() + }) + let actionErrors = UIAlertAction(title: "С ошибками", style: .default, handler: { [weak self] _ in + self?.cardScanner.startScanning() + }) + let actionRetake = UIAlertAction(title: "Переделать", style: .default, handler: { [weak self] _ in + self?.cardScanner.startScanning() + }) + + alert.addAction(actionTrue) + alert.addAction(actionErrors) + alert.addAction(actionRetake) + + present(alert, animated: true, completion: nil) + } } +final class CardFactoryImpl: CardFactory { + let creditCardNumber: Regex = #"(?:\d[ -]*?){13,16}"# + + func create(_ values: [String]) -> Card? { + values.map { + $0.replacingOccurrences(of: " ", with: "") + .replacingOccurrences(of: "-", with: "") + + } + .first { + $0.count >= 15 && $0.count <= 19 && $0.isOnlyNumbers + } + .map { $0.inserting(separator: " ", every: 4) } + .map { Card(number: $0) } + } +} +private extension String { + var isOnlyNumbers: Bool { + return !isEmpty && range(of: "[^0-9]", options: .regularExpression) == nil + } +} + +extension Collection { + func unfoldSubSequences(limitedTo maxLength: Int) -> UnfoldSequence { + sequence(state: startIndex) { start in + guard start < self.endIndex else { return nil } + let end = self.index(start, offsetBy: maxLength, limitedBy: self.endIndex) ?? self.endIndex + defer { start = end } + return self[start.. UnfoldSequence { + sequence(state: startIndex) { index in + guard index < endIndex else { return nil } + defer { index = self.index(index, offsetBy: n, limitedBy: endIndex) ?? endIndex } + return self[index] + } + } + + var pairs: [SubSequence] { .init(unfoldSubSequences(limitedTo: 2)) } +} + +extension StringProtocol where Self: RangeReplaceableCollection { + mutating func insert(separator: S, every n: Int) { + for index in indices.every(n: n).dropFirst().reversed() { + insert(contentsOf: separator, at: index) + } + } + func inserting(separator: S, every n: Int) -> Self { + .init(unfoldSubSequences(limitedTo: n).joined(separator: separator)) + } +}