From d11a31fb16f037cd782ba99bd3a93f955f25e7ed Mon Sep 17 00:00:00 2001 From: Juma Allan Date: Fri, 13 Dec 2024 11:43:00 +0300 Subject: [PATCH 01/14] Fixed Missing Document Type (#264) * added missing document type in document jobs * Update CHANGELOG.md --- CHANGELOG.md | 8 +++++++- .../Model/OrchestratedDocumentVerificationViewModel.swift | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 126fb736..a91f037f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,15 @@ # Release Notes +## Unreleased + +* Fixed missing idType on Document Verification Jobs + ## 10.2.17 -### Added skipApiSubmission: Whether to skip api submission to SmileID and return only captured images on SmartSelfie enrollment, SmartSelfie authentic , Document verification and Enhanced DocV + +* Added skipApiSubmission: Whether to skip api submission to SmileID and return only captured images on SmartSelfie enrollment, SmartSelfie authentic , Document verification and Enhanced DocV ## 10.2.16 + ### Fixed * Clear images on retry or start capture with the same jobId diff --git a/Sources/SmileID/Classes/DocumentVerification/Model/OrchestratedDocumentVerificationViewModel.swift b/Sources/SmileID/Classes/DocumentVerification/Model/OrchestratedDocumentVerificationViewModel.swift index 75425e7a..cdf576d5 100644 --- a/Sources/SmileID/Classes/DocumentVerification/Model/OrchestratedDocumentVerificationViewModel.swift +++ b/Sources/SmileID/Classes/DocumentVerification/Model/OrchestratedDocumentVerificationViewModel.swift @@ -165,7 +165,7 @@ class IOrchestratedDocumentVerificationViewModel: ObservableObj } let info = try LocalStorage.createInfoJsonFile( jobId: jobId, - idInfo: IdInfo(country: countryCode), + idInfo: IdInfo(country: countryCode, idType: documentType), documentFront: frontDocumentUrl, documentBack: backDocumentUrl, selfie: selfieFile, From 81fb13abd520c57f9c3ccbb4636b8aec7493147c Mon Sep 17 00:00:00 2001 From: Tobi Omotayo Date: Fri, 13 Dec 2024 11:03:28 +0100 Subject: [PATCH 02/14] add new submission status icons for success and failed states. --- .../Helpers/SmileIDResourcesHelper.swift | 2 ++ .../Checkmark.imageset/Checkmark.png | Bin 0 -> 1093 bytes .../Checkmark.imageset/Checkmark@2x.png | Bin 0 -> 2039 bytes .../Checkmark.imageset/Checkmark@3x.png | Bin 0 -> 2991 bytes .../Checkmark.imageset/Contents.json | 23 ++++++++++++++++++ .../Xmark.imageset/Contents.json | 23 ++++++++++++++++++ .../Media.xcassets/Xmark.imageset/Xmark.png | Bin 0 -> 1131 bytes .../Xmark.imageset/Xmark@2x.png | Bin 0 -> 2044 bytes .../Xmark.imageset/Xmark@3x.png | Bin 0 -> 3023 bytes 9 files changed, 48 insertions(+) create mode 100644 Sources/SmileID/Resources/Media.xcassets/Checkmark.imageset/Checkmark.png create mode 100644 Sources/SmileID/Resources/Media.xcassets/Checkmark.imageset/Checkmark@2x.png create mode 100644 Sources/SmileID/Resources/Media.xcassets/Checkmark.imageset/Checkmark@3x.png create mode 100644 Sources/SmileID/Resources/Media.xcassets/Checkmark.imageset/Contents.json create mode 100644 Sources/SmileID/Resources/Media.xcassets/Xmark.imageset/Contents.json create mode 100644 Sources/SmileID/Resources/Media.xcassets/Xmark.imageset/Xmark.png create mode 100644 Sources/SmileID/Resources/Media.xcassets/Xmark.imageset/Xmark@2x.png create mode 100644 Sources/SmileID/Resources/Media.xcassets/Xmark.imageset/Xmark@3x.png diff --git a/Sources/SmileID/Classes/Helpers/SmileIDResourcesHelper.swift b/Sources/SmileID/Classes/Helpers/SmileIDResourcesHelper.swift index 38a40a68..9d6597e8 100644 --- a/Sources/SmileID/Classes/Helpers/SmileIDResourcesHelper.swift +++ b/Sources/SmileID/Classes/Helpers/SmileIDResourcesHelper.swift @@ -77,6 +77,8 @@ public class SmileIDResourcesHelper { public static var ConsentDocumentInfo = SmileIDResourcesHelper.image("ConsentDocumentInfo")! public static var ConsentPersonalInfo = SmileIDResourcesHelper.image("ConsentPersonalInfo")! public static var Loader = SmileIDResourcesHelper.image("Loader")! + public static var Checkmark = SmileIDResourcesHelper.image("Checkmark")! + public static var Xmark = SmileIDResourcesHelper.image("Xmark")! /// Size of font. public static let pointSize: CGFloat = 16 diff --git a/Sources/SmileID/Resources/Media.xcassets/Checkmark.imageset/Checkmark.png b/Sources/SmileID/Resources/Media.xcassets/Checkmark.imageset/Checkmark.png new file mode 100644 index 0000000000000000000000000000000000000000..3aaf7483ec7e6e11a01ff18682d3704a49dac350 GIT binary patch literal 1093 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 literal 0 HcmV?d00001 diff --git a/Sources/SmileID/Resources/Media.xcassets/Checkmark.imageset/Checkmark@3x.png b/Sources/SmileID/Resources/Media.xcassets/Checkmark.imageset/Checkmark@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..ca06bbb8a9babb81231788ff7f40e022267fbe93 GIT binary patch literal 2991 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 literal 0 HcmV?d00001 diff --git a/Sources/SmileID/Resources/Media.xcassets/Checkmark.imageset/Contents.json b/Sources/SmileID/Resources/Media.xcassets/Checkmark.imageset/Contents.json new file mode 100644 index 00000000..91ff5752 --- /dev/null +++ b/Sources/SmileID/Resources/Media.xcassets/Checkmark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "Checkmark.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Checkmark@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Checkmark@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/SmileID/Resources/Media.xcassets/Xmark.imageset/Contents.json b/Sources/SmileID/Resources/Media.xcassets/Xmark.imageset/Contents.json new file mode 100644 index 00000000..4d1aa468 --- /dev/null +++ b/Sources/SmileID/Resources/Media.xcassets/Xmark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "Xmark.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Xmark@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Xmark@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/SmileID/Resources/Media.xcassets/Xmark.imageset/Xmark.png b/Sources/SmileID/Resources/Media.xcassets/Xmark.imageset/Xmark.png new file mode 100644 index 0000000000000000000000000000000000000000..9f1fe162a36b947ac295554864d5327039fe2536 GIT binary patch literal 1131 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 R|84*P002ovPDHLkV1j%)b!7km literal 0 HcmV?d00001 From 54ae5ae4ec20edf6cf6c9f05cbca18a358f179ea Mon Sep 17 00:00:00 2001 From: Tobi Omotayo Date: Fri, 13 Dec 2024 11:04:03 +0100 Subject: [PATCH 03/14] remove setting initial value for user instruction. --- .../Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift b/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift index b575a3b9..b0c5046b 100644 --- a/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift +++ b/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift @@ -121,7 +121,6 @@ public class EnhancedSmartSelfieViewModel: ObservableObject { self.livenessCheckManager.delegate = self self.faceValidator.setLayoutGuideFrame(with: faceLayoutGuideFrame) - self.userInstruction = .headInFrame livenessCheckManager.$lookLeftProgress .merge( From 93c8119b7491cf3c264699bfa602b58153c6c55c Mon Sep 17 00:00:00 2001 From: Tobi Omotayo Date: Fri, 13 Dec 2024 11:04:52 +0100 Subject: [PATCH 04/14] handle multiple faces detected and throw an error --- .../SmileID/Classes/FaceDetector/EnhancedFaceDetector.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Sources/SmileID/Classes/FaceDetector/EnhancedFaceDetector.swift b/Sources/SmileID/Classes/FaceDetector/EnhancedFaceDetector.swift index d00eee4a..2806a250 100644 --- a/Sources/SmileID/Classes/FaceDetector/EnhancedFaceDetector.swift +++ b/Sources/SmileID/Classes/FaceDetector/EnhancedFaceDetector.swift @@ -7,6 +7,7 @@ enum FaceDetectorError: Error { case unableToLoadSelfieModel case invalidSelfieModelOutput case noFaceDetected + case multipleFacesDetected case unableToCropImage } @@ -71,6 +72,11 @@ class EnhancedFaceDetector: NSObject { return } + guard faceDetections.count == 1 else { + self.resultDelegate?.faceDetector(self, didFailWithError: FaceDetectorError.multipleFacesDetected) + return + } + let convertedBoundingBox = self.viewDelegate?.convertFromMetadataToPreviewRect( rect: faceObservation.boundingBox) ?? .zero From d957911978bf30c001adc2033a9008e3ccfa2cfa Mon Sep 17 00:00:00 2001 From: Tobi Omotayo Date: Fri, 13 Dec 2024 11:05:44 +0100 Subject: [PATCH 05/14] change order of face validator so that luminance is checked before head position. --- Sources/SmileID/Classes/FaceDetector/FaceValidator.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/SmileID/Classes/FaceDetector/FaceValidator.swift b/Sources/SmileID/Classes/FaceDetector/FaceValidator.swift index 80f54e31..1721bfca 100644 --- a/Sources/SmileID/Classes/FaceDetector/FaceValidator.swift +++ b/Sources/SmileID/Classes/FaceDetector/FaceValidator.swift @@ -89,6 +89,8 @@ final class FaceValidator { } } return nil + } else if !isAcceptableFaceQuality || !isAcceptableBrightness { + return .goodLight } else if faceBoundsState == .detectedFaceOffCentre || faceBoundsState == .detectedFaceNotWithinFrame { return .headInFrame @@ -96,8 +98,6 @@ final class FaceValidator { return .moveCloser } else if faceBoundsState == .detectedFaceTooLarge { return .moveBack - } else if !isAcceptableFaceQuality || !isAcceptableBrightness { - return .goodLight } return nil } From 4fae7e41a2a68499a807d2783cb3ec62f5e45a13 Mon Sep 17 00:00:00 2001 From: Tobi Omotayo Date: Fri, 13 Dec 2024 11:06:56 +0100 Subject: [PATCH 06/14] reduce the stroke size of the face in bounds indicator. --- .../SmileID/Classes/SelfieCapture/View/FaceBoundingArea.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SmileID/Classes/SelfieCapture/View/FaceBoundingArea.swift b/Sources/SmileID/Classes/SelfieCapture/View/FaceBoundingArea.swift index cac02325..4dc7baf3 100644 --- a/Sources/SmileID/Classes/SelfieCapture/View/FaceBoundingArea.swift +++ b/Sources/SmileID/Classes/SelfieCapture/View/FaceBoundingArea.swift @@ -16,7 +16,7 @@ struct FaceBoundingArea: View { faceShape .stroke( faceInBounds ? selfieCaptured ? .clear : SmileID.theme.success : SmileID.theme.error, - style: StrokeStyle(lineWidth: 10) + style: StrokeStyle(lineWidth: 8) ) .frame(width: 270, height: 370) From ba2ec6f441000fc76b8e9da06d4951670ccab4ca Mon Sep 17 00:00:00 2001 From: Tobi Omotayo Date: Fri, 13 Dec 2024 11:21:51 +0100 Subject: [PATCH 07/14] remove done button and hide cancel button if submission was successful. --- .../View/SelfieActionsView.swift | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/Sources/SmileID/Classes/SelfieCapture/View/SelfieActionsView.swift b/Sources/SmileID/Classes/SelfieCapture/View/SelfieActionsView.swift index 789f1979..cf6212e8 100644 --- a/Sources/SmileID/Classes/SelfieCapture/View/SelfieActionsView.swift +++ b/Sources/SmileID/Classes/SelfieCapture/View/SelfieActionsView.swift @@ -1,26 +1,40 @@ import SwiftUI struct SelfieActionsView: View { - var processingState: ProcessingState + var captureState: EnhancedSmartSelfieViewModel.SelfieCaptureState var retryAction: () -> Void - var doneAction: () -> Void + var cancelAction: () -> Void var body: some View { VStack { - Spacer() - switch processingState { - case .inProgress: - EmptyView() - case .success: - SmileButton(title: "Action.Done") { - doneAction() - } - case .error: - SmileButton(title: "Confirmation.Retry") { - retryAction() + // Spacer() + switch captureState { + case .capturingSelfie: + cancelButton + case .processing(let processingState): + switch processingState { + case .inProgress: + cancelButton + case .success: + EmptyView() + case .error: + SmileButton(title: "Confirmation.Retry") { + retryAction() + } + cancelButton } } } .padding(.horizontal, 65) } + + var cancelButton: some View { + Button { + cancelAction() + } label: { + Text(SmileIDResourcesHelper.localizedString(for: "Action.Cancel")) + .font(SmileID.theme.button) + .foregroundColor(SmileID.theme.error) + } + } } From fb16a136465eb41959cff362f3660c78b2ef4875 Mon Sep 17 00:00:00 2001 From: Tobi Omotayo Date: Fri, 13 Dec 2024 11:22:22 +0100 Subject: [PATCH 08/14] use new status icons in status view. --- .../SelfieCapture/View/SubmissionStatusView.swift | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Sources/SmileID/Classes/SelfieCapture/View/SubmissionStatusView.swift b/Sources/SmileID/Classes/SelfieCapture/View/SubmissionStatusView.swift index faab587e..e590d85a 100644 --- a/Sources/SmileID/Classes/SelfieCapture/View/SubmissionStatusView.swift +++ b/Sources/SmileID/Classes/SelfieCapture/View/SubmissionStatusView.swift @@ -9,18 +9,17 @@ struct SubmissionStatusView: View { CircularProgressView() .frame(width: 48, height: 48) case .success: - StatusImage("checkmark.circle.fill", color: SmileID.theme.success) + StatusImage(SmileIDResourcesHelper.Checkmark) case .error: - StatusImage("xmark.circle.fill", color: SmileID.theme.error) + StatusImage(SmileIDResourcesHelper.Xmark) } } // swiftlint:disable identifier_name - @ViewBuilder func StatusImage(_ image: String, color: Color) -> some View { - Image(systemName: image) + @ViewBuilder func StatusImage(_ uiImage: UIImage) -> some View { + Image(uiImage: uiImage) .resizable() .aspectRatio(contentMode: .fill) .frame(width: 48, height: 48) - .foregroundColor(color) } } From ab092d47a10ec3b7bb0a7ca452566f2879a35e46 Mon Sep 17 00:00:00 2001 From: Tobi Omotayo Date: Fri, 13 Dec 2024 11:22:41 +0100 Subject: [PATCH 09/14] add a placeholder for api error 2214 --- .../SmileID/Resources/Localization/en.lproj/Localizable.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/SmileID/Resources/Localization/en.lproj/Localizable.strings b/Sources/SmileID/Resources/Localization/en.lproj/Localizable.strings index 029fed61..252dfa13 100644 --- a/Sources/SmileID/Resources/Localization/en.lproj/Localizable.strings +++ b/Sources/SmileID/Resources/Localization/en.lproj/Localizable.strings @@ -126,6 +126,7 @@ "Si.Error.Message.2211" = ""; "Si.Error.Message.2212" = ""; "Si.Error.Message.2213" = ""; +"Si.Error.Message.2214" = ""; "Si.Error.Message.2413" = ""; "Si.Error.Message.2215" = ""; "Si.Error.Message.2216" = ""; From bebfd82d04d9406d64c74ce827d1bb5d09193701 Mon Sep 17 00:00:00 2001 From: Tobi Omotayo Date: Fri, 13 Dec 2024 11:46:46 +0100 Subject: [PATCH 10/14] update selfie actions view parameters --- .../SelfieCapture/View/EnhancedSelfieCaptureScreen.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/SmileID/Classes/SelfieCapture/View/EnhancedSelfieCaptureScreen.swift b/Sources/SmileID/Classes/SelfieCapture/View/EnhancedSelfieCaptureScreen.swift index 734fe096..4a213a49 100644 --- a/Sources/SmileID/Classes/SelfieCapture/View/EnhancedSelfieCaptureScreen.swift +++ b/Sources/SmileID/Classes/SelfieCapture/View/EnhancedSelfieCaptureScreen.swift @@ -91,9 +91,9 @@ public struct EnhancedSelfieCaptureScreen: View { Spacer() SelfieActionsView( - processingState: processingState, + captureState: viewModel.selfieCaptureState, retryAction: { viewModel.perform(action: .retryJobSubmission) }, - doneAction: { + cancelAction: { modalMode.wrappedValue = false viewModel.perform(action: .jobProcessingDone) } From 342f4e14e9eb806c6c52d3e6a4c90bacf2583f41 Mon Sep 17 00:00:00 2001 From: Tobi Omotayo Date: Fri, 13 Dec 2024 12:17:01 +0100 Subject: [PATCH 11/14] restore camera manager to have accessible initializer. add camera session size preset for selfie capture image --- Sources/SmileID/Classes/Camera/CameraManager.swift | 4 +--- .../Model/DocumentCaptureViewModel.swift | 2 +- .../Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift | 5 ++++- Sources/SmileID/Classes/SelfieCapture/SelfieViewModel.swift | 5 ++++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Sources/SmileID/Classes/Camera/CameraManager.swift b/Sources/SmileID/Classes/Camera/CameraManager.swift index f57cee05..fd5239d7 100644 --- a/Sources/SmileID/Classes/Camera/CameraManager.swift +++ b/Sources/SmileID/Classes/Camera/CameraManager.swift @@ -44,9 +44,7 @@ class CameraManager: NSObject, ObservableObject { @Published private(set) var status = Status.unconfigured private var orientation: Orientation - static let shared: CameraManager = CameraManager(orientation: .portrait) - - private init(orientation: Orientation) { + init(orientation: Orientation) { self.orientation = orientation super.init() sessionQueue.async { diff --git a/Sources/SmileID/Classes/DocumentVerification/Model/DocumentCaptureViewModel.swift b/Sources/SmileID/Classes/DocumentVerification/Model/DocumentCaptureViewModel.swift index d859d9ed..9ac7489a 100644 --- a/Sources/SmileID/Classes/DocumentVerification/Model/DocumentCaptureViewModel.swift +++ b/Sources/SmileID/Classes/DocumentVerification/Model/DocumentCaptureViewModel.swift @@ -39,7 +39,7 @@ class DocumentCaptureViewModel: ObservableObject { @Published var documentImageToConfirm: Data? @Published var captureError: Error? @Published var isCapturing = false - var cameraManager = CameraManager.shared + @Published var cameraManager = CameraManager(orientation: .portrait) init( knownAspectRatio: Double? = nil, diff --git a/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift b/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift index b0c5046b..233ddfde 100644 --- a/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift +++ b/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift @@ -6,7 +6,7 @@ import SwiftUI public class EnhancedSmartSelfieViewModel: ObservableObject { // MARK: Dependencies private let motionManager = CMMotionManager() - let cameraManager = CameraManager.shared + let cameraManager = CameraManager(orientation: .portrait) let faceDetector = EnhancedFaceDetector() private let faceValidator = FaceValidator() var livenessCheckManager = LivenessCheckManager() @@ -135,6 +135,9 @@ public class EnhancedSmartSelfieViewModel: ObservableObject { } .store(in: &subscribers) + if cameraManager.session.canSetSessionPreset(.vga640x480) { + cameraManager.session.sessionPreset = .vga640x480 + } cameraManager.$status .receive(on: DispatchQueue.main) .filter { $0 == .unauthorized } diff --git a/Sources/SmileID/Classes/SelfieCapture/SelfieViewModel.swift b/Sources/SmileID/Classes/SelfieCapture/SelfieViewModel.swift index a3097ca0..984212df 100644 --- a/Sources/SmileID/Classes/SelfieCapture/SelfieViewModel.swift +++ b/Sources/SmileID/Classes/SelfieCapture/SelfieViewModel.swift @@ -28,7 +28,7 @@ public class SelfieViewModel: ObservableObject, ARKitSmileDelegate { private var localMetadata: LocalMetadata private let faceDetector = FaceDetector() - var cameraManager = CameraManager.shared + var cameraManager = CameraManager(orientation: .portrait) var shouldAnalyzeImages = true var lastAutoCaptureTime = Date() var previousHeadRoll = Double.infinity @@ -78,6 +78,9 @@ public class SelfieViewModel: ObservableObject, ARKitSmileDelegate { self.extraPartnerParams = extraPartnerParams self.localMetadata = localMetadata + if cameraManager.session.canSetSessionPreset(.vga640x480) { + cameraManager.session.sessionPreset = .vga640x480 + } cameraManager.$status .receive(on: DispatchQueue.main) .filter { $0 == .unauthorized } From e3f7bce1dfddb951b02a2b756f375c219dffdeb0 Mon Sep 17 00:00:00 2001 From: Tobi Omotayo Date: Fri, 13 Dec 2024 12:18:09 +0100 Subject: [PATCH 12/14] code formatting and set line limit of 2 to user instructions title. --- .../SmileID/Classes/SelfieCapture/View/SelfieActionsView.swift | 3 +-- .../Classes/SelfieCapture/View/UserInstructionsView.swift | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Sources/SmileID/Classes/SelfieCapture/View/SelfieActionsView.swift b/Sources/SmileID/Classes/SelfieCapture/View/SelfieActionsView.swift index cf6212e8..0d3374bd 100644 --- a/Sources/SmileID/Classes/SelfieCapture/View/SelfieActionsView.swift +++ b/Sources/SmileID/Classes/SelfieCapture/View/SelfieActionsView.swift @@ -7,7 +7,6 @@ struct SelfieActionsView: View { var body: some View { VStack { - // Spacer() switch captureState { case .capturingSelfie: cancelButton @@ -27,7 +26,7 @@ struct SelfieActionsView: View { } .padding(.horizontal, 65) } - + var cancelButton: some View { Button { cancelAction() diff --git a/Sources/SmileID/Classes/SelfieCapture/View/UserInstructionsView.swift b/Sources/SmileID/Classes/SelfieCapture/View/UserInstructionsView.swift index a70b7710..79836a43 100644 --- a/Sources/SmileID/Classes/SelfieCapture/View/UserInstructionsView.swift +++ b/Sources/SmileID/Classes/SelfieCapture/View/UserInstructionsView.swift @@ -11,7 +11,7 @@ struct UserInstructionsView: View { .font(SmileID.theme.header2) .foregroundColor(SmileID.theme.onDark) .multilineTextAlignment(.center) - .lineLimit(3) + .lineLimit(2) .minimumScaleFactor(0.8) if let message = message { Text(message) From 6f8f66891f391c3794d2e31fa7a1157049f38943 Mon Sep 17 00:00:00 2001 From: Tobi Omotayo Date: Fri, 13 Dec 2024 14:09:43 +0100 Subject: [PATCH 13/14] change capture screen layout to accommodate small screen devices. remove cancel delegate method from selfie result. --- Example/SmileID/Home/ProductCell.swift | 1 - .../EnhancedSmartSelfieViewModel.swift | 2 - .../SmartSelfieResultDelegate.swift | 5 -- .../View/EnhancedSelfieCaptureScreen.swift | 47 +++++++------------ .../SelfieCapture/View/FaceBoundingArea.swift | 2 +- .../View/SelfiePreviewView.swift | 2 +- 6 files changed, 20 insertions(+), 39 deletions(-) diff --git a/Example/SmileID/Home/ProductCell.swift b/Example/SmileID/Home/ProductCell.swift index d8283b8f..6e6da271 100644 --- a/Example/SmileID/Home/ProductCell.swift +++ b/Example/SmileID/Home/ProductCell.swift @@ -57,7 +57,6 @@ struct ProductCell: View { } } } - .environment(\.modalMode, $isPresented) } ) } diff --git a/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift b/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift index 233ddfde..acddfeee 100644 --- a/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift +++ b/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift @@ -490,8 +490,6 @@ extension EnhancedSmartSelfieViewModel: SelfieSubmissionDelegate { ) } else if let error = error { callback.didError(error: error) - } else { - callback.didCancel() } } diff --git a/Sources/SmileID/Classes/SelfieCapture/SmartSelfieResultDelegate.swift b/Sources/SmileID/Classes/SelfieCapture/SmartSelfieResultDelegate.swift index 3e0680da..afaeadbe 100644 --- a/Sources/SmileID/Classes/SelfieCapture/SmartSelfieResultDelegate.swift +++ b/Sources/SmileID/Classes/SelfieCapture/SmartSelfieResultDelegate.swift @@ -19,8 +19,3 @@ public protocol SmartSelfieResultDelegate { /// - Parameter error: The error returned from a failed selfie capture func didError(error: Error) } - -extension SmartSelfieResultDelegate { - /// The selfie capture operation was canceled. - func didCancel() {} -} diff --git a/Sources/SmileID/Classes/SelfieCapture/View/EnhancedSelfieCaptureScreen.swift b/Sources/SmileID/Classes/SelfieCapture/View/EnhancedSelfieCaptureScreen.swift index 4a213a49..c39dbf3d 100644 --- a/Sources/SmileID/Classes/SelfieCapture/View/EnhancedSelfieCaptureScreen.swift +++ b/Sources/SmileID/Classes/SelfieCapture/View/EnhancedSelfieCaptureScreen.swift @@ -5,9 +5,8 @@ public struct EnhancedSelfieCaptureScreen: View { let showAttribution: Bool private let faceShape = FaceShape() - @Environment(\.modalMode) private var modalMode - private(set) var originalBrightness = UIScreen.main.brightness + private let cameraContainerHeight: CGFloat = 480 public var body: some View { GeometryReader { proxy in @@ -20,14 +19,16 @@ public struct EnhancedSelfieCaptureScreen: View { selfieViewModel: viewModel ) .cornerRadius(40) + .frame(height: cameraContainerHeight) RoundedRectangle(cornerRadius: 40) .fill(SmileID.theme.tertiary.opacity(0.8)) .reverseMask(alignment: .top) { faceShape .frame(width: 250, height: 350) - .padding(.top, 60) + .padding(.top, 50) } + .frame(height: cameraContainerHeight) VStack { ZStack { FaceBoundingArea( @@ -55,7 +56,7 @@ public struct EnhancedSelfieCaptureScreen: View { } } } - .selfieCaptureFrameBackground() + .selfieCaptureFrameBackground(cameraContainerHeight) if showAttribution { Image(uiImage: SmileIDResourcesHelper.SmileEmblem) } @@ -69,8 +70,9 @@ public struct EnhancedSelfieCaptureScreen: View { .reverseMask(alignment: .top) { faceShape .frame(width: 250, height: 350) - .padding(.top, 60) + .padding(.top, 50) } + .frame(height: cameraContainerHeight) VStack { Spacer() UserInstructionsView( @@ -84,33 +86,21 @@ public struct EnhancedSelfieCaptureScreen: View { SubmissionStatusView(processState: processingState) .padding(.bottom, 40) } - .selfieCaptureFrameBackground() + .selfieCaptureFrameBackground(cameraContainerHeight) if showAttribution { Image(uiImage: SmileIDResourcesHelper.SmileEmblem) } - - Spacer() - SelfieActionsView( - captureState: viewModel.selfieCaptureState, - retryAction: { viewModel.perform(action: .retryJobSubmission) }, - cancelAction: { - modalMode.wrappedValue = false - viewModel.perform(action: .jobProcessingDone) - } - ) } - Spacer() - - Button { - modalMode.wrappedValue = false - viewModel.perform(action: .jobProcessingDone) - } label: { - Text(SmileIDResourcesHelper.localizedString(for: "Action.Cancel")) - .font(SmileID.theme.button) - .foregroundColor(SmileID.theme.error) - } + SelfieActionsView( + captureState: viewModel.selfieCaptureState, + retryAction: { viewModel.perform(action: .retryJobSubmission) }, + cancelAction: { + UIApplication.shared.windows.first?.rootViewController?.dismiss(animated: true) + } + ) } + .padding(.vertical, 20) .navigationBarHidden(true) .onAppear { UIScreen.main.brightness = 1 @@ -143,11 +133,10 @@ public struct EnhancedSelfieCaptureScreen: View { } extension View { - func selfieCaptureFrameBackground() -> some View { + func selfieCaptureFrameBackground(_ containerHeight: CGFloat) -> some View { self .shadow(color: .black.opacity(0.25), radius: 4, x: 0, y: 4) - .frame(height: 520) + .frame(height: containerHeight) .padding(.horizontal) - .padding(.top, 40) } } diff --git a/Sources/SmileID/Classes/SelfieCapture/View/FaceBoundingArea.swift b/Sources/SmileID/Classes/SelfieCapture/View/FaceBoundingArea.swift index 4dc7baf3..5e0b1cbd 100644 --- a/Sources/SmileID/Classes/SelfieCapture/View/FaceBoundingArea.swift +++ b/Sources/SmileID/Classes/SelfieCapture/View/FaceBoundingArea.swift @@ -18,7 +18,7 @@ struct FaceBoundingArea: View { faceInBounds ? selfieCaptured ? .clear : SmileID.theme.success : SmileID.theme.error, style: StrokeStyle(lineWidth: 8) ) - .frame(width: 270, height: 370) + .frame(width: 260, height: 360) if let guideAnimation = guideAnimation, showGuideAnimation { diff --git a/Sources/SmileID/Classes/SelfieCapture/View/SelfiePreviewView.swift b/Sources/SmileID/Classes/SelfieCapture/View/SelfiePreviewView.swift index 7687fc9f..fe824010 100644 --- a/Sources/SmileID/Classes/SelfieCapture/View/SelfiePreviewView.swift +++ b/Sources/SmileID/Classes/SelfieCapture/View/SelfiePreviewView.swift @@ -7,7 +7,7 @@ struct SelfiePreviewView: View { Image(uiImage: image) .resizable() .aspectRatio(contentMode: .fill) - .frame(height: 520) + .frame(height: 480) .clipShape(.rect(cornerRadius: 40)) } } From d6a744acf90a423f49236aabdfcf5556cfb928b8 Mon Sep 17 00:00:00 2001 From: Tobi Omotayo Date: Fri, 13 Dec 2024 14:31:27 +0100 Subject: [PATCH 14/14] dismiss the selfie capture when submission is successful. --- .../EnhancedSmartSelfieViewModel.swift | 23 +++++++++++++++++-- .../SelfieCapture/SelfieViewModelAction.swift | 2 +- .../View/EnhancedSelfieCaptureScreen.swift | 2 +- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift b/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift index acddfeee..9c81f3dc 100644 --- a/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift +++ b/Sources/SmileID/Classes/SelfieCapture/EnhancedSmartSelfieViewModel.swift @@ -202,8 +202,8 @@ public class EnhancedSmartSelfieViewModel: ObservableObject { handleWindowSizeChanged(to: windowRect, edgeInsets: safeAreaInsets) case .onViewAppear: handleViewAppeared() - case .jobProcessingDone: - onFinished(callback: onResult) + case .cancelSelfieCapture: + handleCancelSelfieCapture() case .retryJobSubmission: handleSubmission() case .openApplicationSettings: @@ -355,6 +355,21 @@ extension EnhancedSmartSelfieViewModel { guard let settingsURL = URL(string: UIApplication.openSettingsURLString) else { return } UIApplication.shared.open(settingsURL) } + + private func handleCancelSelfieCapture() { + invalidateSubmissionTask() + UIApplication.shared.windows.first?.rootViewController?.dismiss(animated: true) + } + + private func dismissSelfieCapture() { + UIApplication.shared.windows.first?.rootViewController?.dismiss( + animated: true, + completion: { [weak self] in + guard let self else { return } + self.onFinished(callback: self.onResult) + } + ) + } } // MARK: FaceDetectorResultDelegate Methods @@ -502,6 +517,10 @@ extension EnhancedSmartSelfieViewModel: SelfieSubmissionDelegate { self.apiResponse = apiResponse self.selfieCaptureState = .processing(.success) } + + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + self.dismissSelfieCapture() + } } func submissionDidFail( diff --git a/Sources/SmileID/Classes/SelfieCapture/SelfieViewModelAction.swift b/Sources/SmileID/Classes/SelfieCapture/SelfieViewModelAction.swift index 7b9c1c15..2bec66da 100644 --- a/Sources/SmileID/Classes/SelfieCapture/SelfieViewModelAction.swift +++ b/Sources/SmileID/Classes/SelfieCapture/SelfieViewModelAction.swift @@ -6,7 +6,7 @@ enum SelfieViewModelAction { case windowSizeDetected(CGSize, EdgeInsets) // Job Submission Actions - case jobProcessingDone + case cancelSelfieCapture case retryJobSubmission // Others diff --git a/Sources/SmileID/Classes/SelfieCapture/View/EnhancedSelfieCaptureScreen.swift b/Sources/SmileID/Classes/SelfieCapture/View/EnhancedSelfieCaptureScreen.swift index c39dbf3d..f79d7ebb 100644 --- a/Sources/SmileID/Classes/SelfieCapture/View/EnhancedSelfieCaptureScreen.swift +++ b/Sources/SmileID/Classes/SelfieCapture/View/EnhancedSelfieCaptureScreen.swift @@ -96,7 +96,7 @@ public struct EnhancedSelfieCaptureScreen: View { captureState: viewModel.selfieCaptureState, retryAction: { viewModel.perform(action: .retryJobSubmission) }, cancelAction: { - UIApplication.shared.windows.first?.rootViewController?.dismiss(animated: true) + viewModel.perform(action: .cancelSelfieCapture) } ) }