Skip to content

Commit

Permalink
Parametrized orchestrated document verification screen
Browse files Browse the repository at this point in the history
  • Loading branch information
vanshg committed Oct 13, 2023
1 parent aae7559 commit 5f58aea
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,47 +14,46 @@ enum DocumentCaptureFlow: Equatable {
case processing(DocumentProcessingState)
}

class OrchestratedDocumentVerificationViewModel<T>: ObservableObject, SelfieImageCaptureDelegate {
internal class OrchestratedDocumentVerificationViewModel<T>:
ObservableObject,
SelfieImageCaptureDelegate {
// Input properties
private let userId: String
private let jobId: String
private let countryCode: String
private let documentType: String?
private let captureBothSides: Bool
private var selfieFile: Data?
private let jobType: JobType
internal let userId: String
internal let jobId: String
internal let countryCode: String
internal let documentType: String?
internal let captureBothSides: Bool
internal var selfieFile: Data?
internal let jobType: JobType

// Other properties
private var documentFrontFile: Data?
private var documentBackFile: Data?
private var livenessFiles: [Data]?
private var jobStatusResponse: JobStatusResponse?
private var savedFiles: DocumentCaptureResultStore?
private var networkingSubscriber: AnyCancellable?
private var stepToRetry: DocumentCaptureFlow?
private var error: Error?
internal var documentFrontFile: Data?
internal var documentBackFile: Data?
internal var livenessFiles: [Data]?
internal var jobStatusResponse: JobStatusResponse?
internal var savedFiles: DocumentCaptureResultStore?
internal var networkingSubscriber: AnyCancellable?
internal var stepToRetry: DocumentCaptureFlow?
internal var error: Error?

// UI properties
@Published var step = DocumentCaptureFlow.frontDocumentCapture

init(
internal init(
userId: String,
jobId: String,
countryCode: String,
documentType: String?,
captureBothSides: Bool,
selfieFile: URL?,
jobType: JobType = .documentVerification
jobType: JobType
) {
self.userId = userId
self.jobId = jobId
self.countryCode = countryCode
self.documentType = documentType
self.captureBothSides = captureBothSides
self.selfieFile = selfieFile.flatMap { try? Data(contentsOf: $0) }
if jobType != .documentVerification && jobType != .enhancedDocumentVerification {
fatalError("jobType must be documentVerification or enhancedDocumentVerification")
}
self.jobType = jobType
}

Expand Down Expand Up @@ -97,37 +96,8 @@ class OrchestratedDocumentVerificationViewModel<T>: ObservableObject, SelfieImag
submitJob()
}

func onFinished(delegate: DocumentVerificationResultDelegate) {
if let jobStatusResponse = jobStatusResponse, let savedFiles = savedFiles {
delegate.didSucceed(
selfie: savedFiles.selfie,
documentFrontImage: savedFiles.documentFront,
documentBackImage: savedFiles.documentBack,
jobStatusResponse: jobStatusResponse
)
} else if let error = error {
// We check error as the 2nd case because as long as jobStatusResponse is not nil, it
// was a success
delegate.didError(error: error)
} else {
delegate.didError(error: SmileIDError.unknown("Unknown error"))
}
}

/// If stepToRetry is ProcessingScreen, we're retrying a network issue, so we need to kick off
/// the resubmission manually. Otherwise, we're retrying a capture error, so we just need to
/// reset the UI state
func onRetry() {
let step = stepToRetry
stepToRetry = nil
if let stepToRetry = step {
DispatchQueue.main.async {
self.step = stepToRetry
}
if case .processing = stepToRetry {
submitJob()
}
}
func onFinished(delegate: T) {
fatalError("Must override onFinished")
}

func submitJob() {
Expand Down Expand Up @@ -215,4 +185,60 @@ class OrchestratedDocumentVerificationViewModel<T>: ObservableObject, SelfieImag
}
)
}

/// If stepToRetry is ProcessingScreen, we're retrying a network issue, so we need to kick off
/// the resubmission manually. Otherwise, we're retrying a capture error, so we just need to
/// reset the UI state
func onRetry() {
let step = stepToRetry
stepToRetry = nil
if let stepToRetry = step {
DispatchQueue.main.async {
self.step = stepToRetry
}
if case .processing = stepToRetry {
submitJob()
}
}
}
}

internal class OrchestratedDocumentVerificationViewModelImpl:
OrchestratedDocumentVerificationViewModel<DocumentVerificationResultDelegate> {
override func onFinished(delegate: DocumentVerificationResultDelegate) {
if let jobStatusResponse = jobStatusResponse, let savedFiles = savedFiles {
delegate.didSucceed(
selfie: savedFiles.selfie,
documentFrontImage: savedFiles.documentFront,
documentBackImage: savedFiles.documentBack,
jobStatusResponse: jobStatusResponse
)
} else if let error = error {
// We check error as the 2nd case because as long as jobStatusResponse is not nil, it
// was a success
delegate.didError(error: error)
} else {
delegate.didError(error: SmileIDError.unknown("Unknown error"))
}
}
}

internal class OrchestratedEnhancedDocumentVerificationViewModel:
OrchestratedDocumentVerificationViewModel<EnhancedDocumentVerificationResultDelegate> {
override func onFinished(delegate: EnhancedDocumentVerificationResultDelegate) {
if let jobStatusResponse = jobStatusResponse, let savedFiles = savedFiles {
delegate.didSucceed(
selfie: savedFiles.selfie,
documentFrontImage: savedFiles.documentFront,
documentBackImage: savedFiles.documentBack,
jobStatusResponse: jobStatusResponse
)
} else if let error = error {
// We check error as the 2nd case because as long as jobStatusResponse is not nil, it
// was a success
delegate.didError(error: error)
} else {
delegate.didError(error: SmileIDError.unknown("Unknown error"))
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import SwiftUI

struct OrchestratedDocumentVerificationScreen: View {
struct OrchestratedDocumentVerificationScreen<T>: View {
let countryCode: String
let documentType: String?
let captureBothSides: Bool
Expand All @@ -11,9 +11,9 @@ struct OrchestratedDocumentVerificationScreen: View {
let showAttribution: Bool
let allowGalleryUpload: Bool
let showInstructions: Bool
let onResult: DocumentVerificationResultDelegate
let onResult: T

@ObservedObject private var viewModel: OrchestratedDocumentVerificationViewModel
@ObservedObject private var viewModel: OrchestratedDocumentVerificationViewModel<T>

init(
countryCode: String,
Expand All @@ -26,7 +26,8 @@ struct OrchestratedDocumentVerificationScreen: View {
showAttribution: Bool,
allowGalleryUpload: Bool,
showInstructions: Bool,
onResult: DocumentVerificationResultDelegate
jobType: JobType,
onResult: T
) {
self.countryCode = countryCode
self.documentType = documentType
Expand All @@ -39,14 +40,29 @@ struct OrchestratedDocumentVerificationScreen: View {
self.allowGalleryUpload = allowGalleryUpload
self.showInstructions = showInstructions
self.onResult = onResult
viewModel = OrchestratedDocumentVerificationViewModel(
userId: userId,
jobId: jobId,
countryCode: countryCode,
documentType: documentType,
captureBothSides: captureBothSides,
selfieFile: bypassSelfieCaptureWithFile
)
// swiftlint:disable force_cast
if jobType == .enhancedDocumentVerification {
viewModel = OrchestratedEnhancedDocumentVerificationViewModel(
userId: userId,
jobId: jobId,
countryCode: countryCode,
documentType: documentType,
captureBothSides: captureBothSides,
selfieFile: bypassSelfieCaptureWithFile,
jobType: jobType
) as! OrchestratedDocumentVerificationViewModel<T>
} else {
viewModel = OrchestratedDocumentVerificationViewModelImpl(
userId: userId,
jobId: jobId,
countryCode: countryCode,
documentType: documentType,
captureBothSides: captureBothSides,
selfieFile: bypassSelfieCaptureWithFile,
jobType: jobType
) as! OrchestratedDocumentVerificationViewModel<T>
}
// swiftlint:enable force_cast
}

var body: some View {
Expand Down
15 changes: 8 additions & 7 deletions Sources/SmileID/Classes/SmileID.swift
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ public class SmileID {
showAttribution: showAttribution,
allowGalleryUpload: allowGalleryUpload,
showInstructions: showInstructions,
jobType: .documentVerification,
onResult: delegate
).environmentObject(router)
}
Expand Down Expand Up @@ -250,19 +251,19 @@ public class SmileID {
showAttribution: Bool = true,
delegate: DocumentVerificationResultDelegate
) -> some View {
// TODO: parametrize
documentVerificationScreen(
userId: userId,
jobId: jobId,
OrchestratedDocumentVerificationScreen(
countryCode: countryCode,
documentType: documentType,
captureBothSides: captureBothSides,
idAspectRatio: idAspectRatio,
bypassSelfieCaptureWithFile: bypassSelfieCaptureWithFile,
captureBothSides: captureBothSides,
userId: userId,
jobId: jobId,
showAttribution: showAttribution,
allowGalleryUpload: allowGalleryUpload,
showInstructions: showInstructions,
showAttribution: showAttribution,
delegate: delegate
jobType: .enhancedDocumentVerification,
onResult: delegate
).environmentObject(router)
}
}

0 comments on commit 5f58aea

Please sign in to comment.