@smile_identity/react-native 10.2.4-beta.1 → 10.2.5

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.
Files changed (70) hide show
  1. package/android/build.gradle +2 -1
  2. package/android/gradle.properties +1 -1
  3. package/android/src/main/java/com/smileidentity/react/Mapper.kt +1 -1
  4. package/android/src/main/java/com/smileidentity/react/viewmanagers/SmileIDBiometricKYCViewManager.kt +1 -0
  5. package/android/src/main/java/com/smileidentity/react/viewmanagers/SmileIDDocumentVerificationViewManager.kt +1 -0
  6. package/android/src/main/java/com/smileidentity/react/viewmanagers/SmileIDEnhancedDocumentVerificationViewManager.kt +1 -0
  7. package/android/src/main/java/com/smileidentity/react/views/SmileIDBiometricKYCView.kt +2 -0
  8. package/android/src/main/java/com/smileidentity/react/views/SmileIDDocumentVerificationView.kt +2 -0
  9. package/android/src/main/java/com/smileidentity/react/views/SmileIDEnhancedDocumentVerificationView.kt +2 -0
  10. package/ios/RNDelegates/SmileIDUIViewDelegate.swift +2 -0
  11. package/ios/RNSmileID.swift +482 -471
  12. package/ios/Utils/FileUtils.swift +17 -17
  13. package/ios/Utils/SmileIDDictExt.swift +29 -9
  14. package/ios/Utils/SmileIDUtils.swift +9 -0
  15. package/ios/View/BaseSmileIDView.swift +6 -5
  16. package/ios/View/SmileIDBiometricKYCView.swift +56 -54
  17. package/ios/View/SmileIDConsentView.swift +3 -2
  18. package/ios/View/SmileIDDocumentCaptureView.swift +64 -64
  19. package/ios/View/SmileIDDocumentVerificationView.swift +52 -51
  20. package/ios/View/SmileIDEnhancedDocumentVerificationView.swift +53 -50
  21. package/ios/View/SmileIDSmartSelfieAuthEnhancedView.swift +34 -33
  22. package/ios/View/SmileIDSmartSelfieAuthView.swift +35 -34
  23. package/ios/View/SmileIDSmartSelfieCaptureView.swift +55 -55
  24. package/ios/View/SmileIDSmartSelfieEnrollmentEnhancedView.swift +35 -34
  25. package/ios/View/SmileIDSmartSelfieEnrollmentView.swift +37 -36
  26. package/ios/ViewManagers/SmileIDBaseViewManager.swift +38 -25
  27. package/ios/ViewManagers/SmileIDBiometricKYCViewManager.swift +30 -24
  28. package/ios/ViewManagers/SmileIDConsentViewManager.swift +2 -2
  29. package/ios/ViewManagers/SmileIDDocumentCaptureViewManager.swift +19 -19
  30. package/ios/ViewManagers/SmileIDDocumentVerificationViewManager.swift +41 -40
  31. package/ios/ViewManagers/SmileIDEnhancedDocumentVerificationViewManager.swift +47 -40
  32. package/ios/ViewManagers/SmileIDSmartSelfieAuthenticationEnhancedViewManager.swift +16 -16
  33. package/ios/ViewManagers/SmileIDSmartSelfieAuthenticationViewManager.swift +20 -20
  34. package/ios/ViewManagers/SmileIDSmartSelfieCaptureViewManager.swift +27 -26
  35. package/ios/ViewManagers/SmileIDSmartSelfieEnrollmentEnhancedViewManager.swift +16 -16
  36. package/ios/ViewManagers/SmileIDSmartSelfieEnrollmentViewManager.swift +20 -20
  37. package/ios/ViewModels/SmileIDProductModel.swift +7 -5
  38. package/lib/commonjs/SmileIDBiometricKYCView.js +2 -11
  39. package/lib/commonjs/SmileIDBiometricKYCView.js.map +1 -1
  40. package/lib/commonjs/SmileIDEnhancedDocumentVerificationView.js +2 -11
  41. package/lib/commonjs/SmileIDEnhancedDocumentVerificationView.js.map +1 -1
  42. package/lib/commonjs/index.js.map +1 -1
  43. package/lib/commonjs/types.js +31 -1
  44. package/lib/commonjs/types.js.map +1 -1
  45. package/lib/commonjs/useSmileIDView.js +16 -6
  46. package/lib/commonjs/useSmileIDView.js.map +1 -1
  47. package/lib/module/SmileIDBiometricKYCView.js +2 -11
  48. package/lib/module/SmileIDBiometricKYCView.js.map +1 -1
  49. package/lib/module/SmileIDEnhancedDocumentVerificationView.js +2 -11
  50. package/lib/module/SmileIDEnhancedDocumentVerificationView.js.map +1 -1
  51. package/lib/module/index.js.map +1 -1
  52. package/lib/module/types.js +29 -0
  53. package/lib/module/types.js.map +1 -1
  54. package/lib/module/useSmileIDView.js +17 -7
  55. package/lib/module/useSmileIDView.js.map +1 -1
  56. package/lib/typescript/SmileIDBiometricKYCView.d.ts.map +1 -1
  57. package/lib/typescript/SmileIDEnhancedDocumentVerificationView.d.ts +2 -2
  58. package/lib/typescript/SmileIDEnhancedDocumentVerificationView.d.ts.map +1 -1
  59. package/lib/typescript/index.d.ts +2 -2
  60. package/lib/typescript/index.d.ts.map +1 -1
  61. package/lib/typescript/types.d.ts +17 -3
  62. package/lib/typescript/types.d.ts.map +1 -1
  63. package/lib/typescript/useSmileIDView.d.ts.map +1 -1
  64. package/package.json +1 -1
  65. package/react-native-smile-id.podspec +1 -1
  66. package/src/SmileIDBiometricKYCView.tsx +2 -9
  67. package/src/SmileIDEnhancedDocumentVerificationView.tsx +6 -16
  68. package/src/index.tsx +2 -0
  69. package/src/types.ts +62 -3
  70. package/src/useSmileIDView.tsx +17 -9
@@ -1,24 +1,24 @@
1
1
  protocol SmileIDFileUtilsProtocol {
2
- var fileManager: FileManager { get set }
3
- func getFilePath(fileName: String) -> String?
2
+ var fileManager: FileManager { get set }
3
+ func getFilePath(fileName: String) -> String?
4
4
  }
5
5
 
6
6
  extension SmileIDFileUtilsProtocol {
7
- func getSmileIDDirectory() -> String? {
8
- guard let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else {
9
- print("Unable to access documents directory")
10
- return nil
7
+ func getSmileIDDirectory() -> String? {
8
+ guard let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else {
9
+ print("Unable to access documents directory")
10
+ return nil
11
+ }
12
+
13
+ let smileIDDirectory = documentsDirectory.appendingPathComponent("SmileID")
14
+ return smileIDDirectory.absoluteURL.absoluteString
11
15
  }
12
-
13
- let smileIDDirectory = documentsDirectory.appendingPathComponent("SmileID")
14
- return smileIDDirectory.absoluteURL.absoluteString
15
- }
16
-
17
- func getFilePath(fileName: String) -> String? {
18
- guard let smileIDDirectory = getSmileIDDirectory() else {
19
- return nil
16
+
17
+ func getFilePath(fileName: String) -> String? {
18
+ guard let smileIDDirectory = getSmileIDDirectory() else {
19
+ return nil
20
+ }
21
+
22
+ return (smileIDDirectory as NSString).appendingPathComponent(fileName)
20
23
  }
21
-
22
- return (smileIDDirectory as NSString).appendingPathComponent(fileName)
23
- }
24
24
  }
@@ -2,21 +2,21 @@ import Foundation
2
2
  import SmileID
3
3
 
4
4
  extension NSDictionary {
5
-
6
5
  func toConfig() -> Config {
7
- return Config (
6
+ return Config(
8
7
  partnerId: (self["partnerId"] as? String)!,
9
8
  authToken: (self["authToken"] as? String)!,
10
9
  prodLambdaUrl: (self["prodLambdaUrl"] as? String)!,
11
10
  testLambdaUrl: (self["testLambdaUrl"] as? String)!
12
11
  )
13
12
  }
14
-
13
+
15
14
  func toAuthenticationRequest() -> AuthenticationRequest? {
16
15
  guard let jobTypeValue = self["jobType"] as? Int,
17
16
  let jobType = JobType(rawValue: jobTypeValue),
18
17
  let jobId = self["jobId"] as? String,
19
- let userId = self["userId"] as? String else {
18
+ let userId = self["userId"] as? String
19
+ else {
20
20
  return nil
21
21
  }
22
22
 
@@ -40,7 +40,8 @@ extension NSDictionary {
40
40
  let callbackUrl = self["callbackUrl"] as? String,
41
41
  let partnerId = self["partnerId"] as? String,
42
42
  let timestamp = self["timestamp"] as? String,
43
- let signature = self["signature"] as? String else {
43
+ let signature = self["signature"] as? String
44
+ else {
44
45
  return nil
45
46
  }
46
47
 
@@ -70,7 +71,8 @@ extension NSDictionary {
70
71
  func toUploadImageInfo() -> UploadImageInfo? {
71
72
  guard let imageTypeIdValue = self["imageTypeId"] as? String,
72
73
  let imageTypeId = ImageType(rawValue: imageTypeIdValue),
73
- let imageName = self["imageName"] as? String else {
74
+ let imageName = self["imageName"] as? String
75
+ else {
74
76
  return nil
75
77
  }
76
78
 
@@ -107,6 +109,19 @@ extension NSDictionary {
107
109
  )
108
110
  }
109
111
 
112
+ func toConsentInfo() -> ConsentInformation {
113
+ let consentGrantedDate = self["consentGrantedDate"] as? String ?? getCurrentIsoTimestamp()
114
+ let personalDetailsConsentGranted = self["personalDetailsConsentGranted"] as? Bool ?? false
115
+ let contactInfoConsentGranted = self["contactInfoConsentGranted"] as? Bool ?? false
116
+ let documentInfoConsentGranted = self["documentInfoConsentGranted"] as? Bool ?? false
117
+ return ConsentInformation(
118
+ consentGrantedDate: consentGrantedDate,
119
+ personalDetailsConsentGranted: personalDetailsConsentGranted,
120
+ contactInformationConsentGranted: contactInfoConsentGranted,
121
+ documentInformationConsentGranted: documentInfoConsentGranted
122
+ )
123
+ }
124
+
110
125
  func toEnhancedKycRequest() -> EnhancedKycRequest? {
111
126
  guard let country = self["country"] as? String,
112
127
  let idType = self["idType"] as? String,
@@ -119,9 +134,11 @@ extension NSDictionary {
119
134
  let bankCode = self["bankCode"] as? String,
120
135
  let callbackUrl = self["callbackUrl"] as? String,
121
136
  let partnerParamsDict = self["partnerParams"] as? NSDictionary,
137
+ let consentInformation = self["consentInformation"] as? NSDictionary,
122
138
  let partnerParams = partnerParamsDict.toPartnerParams(),
123
139
  let timestamp = self["timestamp"] as? String,
124
- let signature = self["signature"] as? String else {
140
+ let signature = self["signature"] as? String
141
+ else {
125
142
  return nil
126
143
  }
127
144
 
@@ -129,6 +146,7 @@ extension NSDictionary {
129
146
  country: country,
130
147
  idType: idType,
131
148
  idNumber: idNumber,
149
+ consentInformation: consentInformation.toConsentInfo(),
132
150
  firstName: firstName,
133
151
  middleName: middleName,
134
152
  lastName: lastName,
@@ -150,7 +168,8 @@ extension NSDictionary {
150
168
  let includeHistory = self["includeHistory"] as? Bool,
151
169
  let partnerId = self["partnerId"] as? String,
152
170
  let timestamp = self["timestamp"] as? String,
153
- let signature = self["signature"] as? String else {
171
+ let signature = self["signature"] as? String
172
+ else {
154
173
  return nil
155
174
  }
156
175
 
@@ -168,7 +187,8 @@ extension NSDictionary {
168
187
  func toProductsConfigRequest() -> ProductsConfigRequest? {
169
188
  guard let partnerId = self["partnerId"] as? String,
170
189
  let timestamp = self["timestamp"] as? String,
171
- let signature = self["signature"] as? String else {
190
+ let signature = self["signature"] as? String
191
+ else {
172
192
  return nil
173
193
  }
174
194
 
@@ -8,3 +8,12 @@ extension String {
8
8
  return false
9
9
  }
10
10
  }
11
+
12
+ func getCurrentIsoTimestamp() -> String {
13
+ let pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
14
+ let formatter = DateFormatter()
15
+ formatter.dateFormat = pattern
16
+ formatter.locale = Locale(identifier: "en_US")
17
+ formatter.timeZone = TimeZone(identifier: "UTC")
18
+ return formatter.string(from: Date())
19
+ }
@@ -3,9 +3,9 @@ import SwiftUI
3
3
 
4
4
  class BaseSmileIDView: UIView {
5
5
  typealias ContentView = AnyView
6
- var contentView : AnyView?
6
+ var contentView: AnyView?
7
7
  private var _onResult: RCTBubblingEventBlock?
8
- var product : SmileIDProductModel?
8
+ var product: SmileIDProductModel?
9
9
 
10
10
  @objc var onResult: RCTBubblingEventBlock? {
11
11
  get {
@@ -19,7 +19,7 @@ class BaseSmileIDView: UIView {
19
19
  }
20
20
  }
21
21
 
22
- init(frame: CGRect,contentView:AnyView,product:SmileIDProductModel) {
22
+ init(frame: CGRect, contentView: AnyView, product: SmileIDProductModel) {
23
23
  self.contentView = contentView
24
24
  self.product = product
25
25
  super.init(frame: frame)
@@ -34,7 +34,7 @@ class BaseSmileIDView: UIView {
34
34
  private func commonInit() {
35
35
  // Perform initialization tasks here
36
36
  // For example, setup subviews, add constraints, configure appearance
37
- let hostingController = UIHostingController(rootView:contentView)
37
+ let hostingController = UIHostingController(rootView: contentView)
38
38
  let hostingView = hostingController.view!
39
39
  hostingView.translatesAutoresizingMaskIntoConstraints = false
40
40
  addSubview(hostingView)
@@ -42,9 +42,10 @@ class BaseSmileIDView: UIView {
42
42
  hostingView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
43
43
  hostingView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
44
44
  hostingView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
45
+ hostingView.overrideUserInterfaceStyle = .light
45
46
  }
46
47
 
47
- func getView(product:SmileIDProductModel) -> AnyView {
48
+ func getView(product _: SmileIDProductModel) -> AnyView {
48
49
  fatalError("Must be implemented by subclass")
49
50
  }
50
51
  }
@@ -2,62 +2,64 @@ import Foundation
2
2
  import SmileID
3
3
  import SwiftUI
4
4
 
5
- struct SmileIDBiometricKYCView: View ,SmileIDFileUtilsProtocol {
6
- var fileManager: FileManager = Foundation.FileManager.default
7
- @ObservedObject var product : SmileIDProductModel
8
- var body: some View{
9
- NavigationView {
10
- if let idInfo = product.idInfo {
11
- SmileID.biometricKycScreen(
12
- idInfo: idInfo, // already validated in the SmileIDBiometricKYCViewManager
13
- userId: product.userId ?? generateUserId(),
14
- jobId: product.jobId ?? generateJobId(),
15
- allowNewEnroll: product.allowNewEnroll,
16
- allowAgentMode: product.allowAgentMode,
17
- showAttribution: product.showAttribution,
18
- showInstructions: product.showInstructions,
19
- extraPartnerParams: product.extraPartnerParams as [String: String],
20
- delegate: self
21
- )
22
- } else {
23
- // This exists for debugging purposes and will show in extreme cases
24
- // when the params were not set NB: setParams in the viewmanager will always
25
- // return an error if the required data is missing
26
- Text("An error has occured")
27
- }
28
- }.navigationViewStyle(StackNavigationViewStyle())
29
- }
5
+ struct SmileIDBiometricKYCView: View, SmileIDFileUtilsProtocol {
6
+ var fileManager: FileManager = Foundation.FileManager.default
7
+ @ObservedObject var product: SmileIDProductModel
8
+ var smileIDUIViewDelegate: SmileIDUIViewDelegate
9
+ var body: some View {
10
+ NavigationView {
11
+ if let idInfo = product.idInfo, let consentInformation = product.consentInformation {
12
+ SmileID.biometricKycScreen(
13
+ idInfo: idInfo,
14
+ consentInformation: consentInformation, // already validated in the SmileIDBiometricKYCViewManager
15
+ userId: product.userId ?? generateUserId(),
16
+ jobId: product.jobId ?? generateJobId(),
17
+ allowNewEnroll: product.allowNewEnroll,
18
+ allowAgentMode: product.allowAgentMode,
19
+ showAttribution: product.showAttribution,
20
+ showInstructions: product.showInstructions,
21
+ useStrictMode: product.useStrictMode,
22
+ extraPartnerParams: product.extraPartnerParams as [String: String],
23
+ delegate: self
24
+ )
25
+ } else {
26
+ // This exists for debugging purposes and will show in extreme cases
27
+ // when the params were not set NB: setParams in the viewmanager will always
28
+ // return an error if the required data is missing
29
+ Text("An error has occured")
30
+ }
31
+ }.navigationViewStyle(StackNavigationViewStyle())
32
+ }
30
33
  }
31
34
 
32
35
  extension SmileIDBiometricKYCView: BiometricKycResultDelegate {
33
- func didSucceed(selfieImage: URL, livenessImages: [URL], didSubmitBiometricJob: Bool) {
34
-
35
- let params: [String: Any] = [
36
- "selfieFile": getFilePath(fileName: selfieImage.absoluteString),
37
- "livenessFiles": livenessImages.map {
38
- getFilePath(fileName: $0.absoluteString)
39
- },
40
- "didSubmitBiometricKycJob": didSubmitBiometricJob,
41
- ]
42
-
43
- guard let jsonData = try? JSONSerialization.data(withJSONObject: params.toJSONCompatibleDictionary(), options: .prettyPrinted) else {
44
- product.onResult?(["error": SmileIDError.unknown("SmileIDBiometricKYCView encoding error")])
45
- return
36
+ func didSucceed(selfieImage: URL, livenessImages: [URL], didSubmitBiometricJob: Bool) {
37
+ let params: [String: Any] = [
38
+ "selfieFile": getFilePath(fileName: selfieImage.absoluteString),
39
+ "livenessFiles": livenessImages.map {
40
+ getFilePath(fileName: $0.absoluteString)
41
+ },
42
+ "didSubmitBiometricKycJob": didSubmitBiometricJob,
43
+ ]
44
+
45
+ guard let jsonData = try? JSONSerialization.data(withJSONObject: params.toJSONCompatibleDictionary(), options: .prettyPrinted) else {
46
+ smileIDUIViewDelegate.onError(error: SmileIDError.unknown("SmileIDBiometricKYCView encoding error"))
47
+ return
48
+ }
49
+ smileIDUIViewDelegate.onResult(smileResult: String(data: jsonData, encoding: .utf8)!)
50
+ }
51
+
52
+ func didSucceed(
53
+ selfieImage _: URL,
54
+ livenessImages _: [URL],
55
+ jobStatusResponse: BiometricKycJobStatusResponse
56
+ ) {
57
+ let encoder = JSONEncoder()
58
+ let jsonData = try! encoder.encode(jobStatusResponse)
59
+ smileIDUIViewDelegate.onResult(smileResult: String(data: jsonData, encoding: .utf8)!)
60
+ }
61
+
62
+ func didError(error: Error) {
63
+ smileIDUIViewDelegate.onError(error: error)
46
64
  }
47
- product.onResult?(["result": String(data: jsonData, encoding: .utf8)!])
48
- }
49
-
50
- func didSucceed(
51
- selfieImage _: URL,
52
- livenessImages _: [URL],
53
- jobStatusResponse: BiometricKycJobStatusResponse
54
- ) {
55
- let encoder = JSONEncoder()
56
- let jsonData = try! encoder.encode(jobStatusResponse)
57
- product.onResult?(["result": String(data: jsonData, encoding: .utf8)!])
58
- }
59
-
60
- func didError(error: Error) {
61
- product.onResult?(["error": error.localizedDescription])
62
- }
63
65
  }
@@ -3,8 +3,9 @@ import SmileID
3
3
  import SwiftUI
4
4
 
5
5
  struct SmileIDConsentView: View {
6
- @ObservedObject var product : SmileIDProductModel
6
+ @ObservedObject var product: SmileIDProductModel
7
7
  var onResult: RCTBubblingEventBlock?
8
+ var smileIDUIViewDelegate: SmileIDUIViewDelegate
8
9
  var body: some View {
9
10
  NavigationView {
10
11
  if let partnerIcon = product.partnerIcon,
@@ -19,7 +20,7 @@ struct SmileIDConsentView: View {
19
20
  productName: productName,
20
21
  partnerPrivacyPolicy: URL(string: partnerPrivacyPolicy)!,
21
22
  showAttribution: true,
22
- onConsentGranted: {
23
+ onConsentGranted: { _ in
23
24
  DispatchQueue.main.async {
24
25
  self.product.onResult?(["result": true])
25
26
  }
@@ -3,80 +3,80 @@ import SmileID
3
3
  import SwiftUI
4
4
 
5
5
  struct DocumentCaptureResult {
6
- let documentFile: URL? // Using URL to represent file paths in Swift
6
+ let documentFile: URL? // Using URL to represent file paths in Swift
7
7
 
8
- init(documentFile: URL?) {
9
- self.documentFile = documentFile
10
- }
8
+ init(documentFile: URL?) {
9
+ self.documentFile = documentFile
10
+ }
11
11
  }
12
12
 
13
13
  struct SmileIDDocumentCaptureView: View {
14
- @ObservedObject var product : SmileIDProductModel
15
- @State private var localMetadata = LocalMetadata()
16
- var body: some View {
17
- NavigationView {
18
- DocumentCaptureScreen(
19
- side: self.product.front ? .front : .back,
20
- showInstructions: self.product.showInstructions,
21
- showAttribution: self.product.showAttribution,
22
- allowGallerySelection: self.product.allowGalleryUpload,
23
- showSkipButton: false,
24
- instructionsHeroImage: self.product.front ? SmileIDResourcesHelper.DocVFrontHero : SmileIDResourcesHelper.DocVBackHero,
25
- instructionsTitleText: SmileIDResourcesHelper.localizedString(
26
- for: self.product.front ? "Instructions.Document.Front.Header": "Instructions.Document.Back.Header"
27
- ),
28
- instructionsSubtitleText: SmileIDResourcesHelper.localizedString(
29
- for: self.product.front ? "Instructions.Document.Front.Callout": "Instructions.Document.Back.Callout"
30
- ),
31
- captureTitleText: SmileIDResourcesHelper.localizedString(for: "Action.TakePhoto"),
32
- knownIdAspectRatio: self.product.idAspectRatio,
33
- showConfirmation:self.product.showConfirmation,
34
- onConfirm: onConfirmed,
35
- onError: onError,
36
- onSkip: onSkip
37
- )
38
- }.navigationViewStyle(StackNavigationViewStyle()).environmentObject(localMetadata)
39
- }
40
-
41
- func onConfirmed(data: Data) {
42
- do {
43
- // Attempt to create the document file
44
- let url = try LocalStorage.createDocumentFile(
45
- jobId: self.product.jobId ?? generateJobId(),
46
- fileType: self.product.front ? FileType.documentFront : FileType.documentBack,
47
- document: data
48
- )
14
+ @ObservedObject var product: SmileIDProductModel
15
+ @State private var localMetadata = LocalMetadata()
16
+ var smileIDUIViewDelegate: SmileIDUIViewDelegate
17
+ var body: some View {
18
+ NavigationView {
19
+ DocumentCaptureScreen(
20
+ side: self.product.front ? .front : .back,
21
+ showInstructions: self.product.showInstructions,
22
+ showAttribution: self.product.showAttribution,
23
+ allowGallerySelection: self.product.allowGalleryUpload,
24
+ showSkipButton: false,
25
+ instructionsHeroImage: self.product.front ? SmileIDResourcesHelper.DocVFrontHero : SmileIDResourcesHelper.DocVBackHero,
26
+ instructionsTitleText: SmileIDResourcesHelper.localizedString(
27
+ for: self.product.front ? "Instructions.Document.Front.Header" : "Instructions.Document.Back.Header"
28
+ ),
29
+ instructionsSubtitleText: SmileIDResourcesHelper.localizedString(
30
+ for: self.product.front ? "Instructions.Document.Front.Callout" : "Instructions.Document.Back.Callout"
31
+ ),
32
+ captureTitleText: SmileIDResourcesHelper.localizedString(for: "Action.TakePhoto"),
33
+ knownIdAspectRatio: self.product.idAspectRatio,
34
+ showConfirmation: self.product.showConfirmation,
35
+ onConfirm: onConfirmed,
36
+ onError: onError,
37
+ onSkip: onSkip
38
+ )
39
+ }.navigationViewStyle(StackNavigationViewStyle()).environmentObject(localMetadata)
40
+ }
49
41
 
42
+ func onConfirmed(data: Data) {
43
+ do {
44
+ // Attempt to create the document file
45
+ let url = try LocalStorage.createDocumentFile(
46
+ jobId: product.jobId ?? generateJobId(),
47
+ fileType: product.front ? FileType.documentFront : FileType.documentBack,
48
+ document: data
49
+ )
50
50
 
51
- // Create params dictionary
52
- var params: [String: Any] = [
53
- "documentFrontImage": product.front ? url.absoluteString : nil ,
54
- "documentBackImage": product.front ? nil : url.absoluteString
55
- ]
51
+ // Create params dictionary
52
+ var params: [String: Any] = [
53
+ "documentFrontImage": product.front ? url.absoluteString : nil,
54
+ "documentBackImage": product.front ? nil : url.absoluteString,
55
+ ]
56
56
 
57
- // Convert params to JSON-compatible dictionary and serialize to JSON
58
- guard let jsonData = try? JSONSerialization.data(withJSONObject: params.toJSONCompatibleDictionary(), options: .prettyPrinted),
59
- let jsonString = String(data: jsonData, encoding: .utf8) else {
60
- // If serialization fails, call the error handler
61
- product.onResult?(["error": SmileIDError.unknown("SmileIDDocumentCaptureView encoding error")])
62
- return
63
- }
57
+ // Convert params to JSON-compatible dictionary and serialize to JSON
58
+ guard let jsonData = try? JSONSerialization.data(withJSONObject: params.toJSONCompatibleDictionary(), options: .prettyPrinted),
59
+ let jsonString = String(data: jsonData, encoding: .utf8)
60
+ else {
61
+ // If serialization fails, call the error handler
62
+ smileIDUIViewDelegate.onError(error: SmileIDError.unknown("SmileIDDocumentCaptureView encoding error"))
63
+ return
64
+ }
64
65
 
65
- // Send the result as a JSON string
66
- product.onResult?(["result": jsonString])
66
+ // Send the result as a JSON string
67
+ smileIDUIViewDelegate.onResult(smileResult: jsonString)
67
68
 
68
- } catch {
69
- // Handle file creation error
70
- product.onResult?(["error": SmileIDError.unknown("Error creating document file: \(error.localizedDescription)")])
69
+ } catch {
70
+ // Handle file creation error
71
+ smileIDUIViewDelegate.onError(error: SmileIDError.unknown("Error creating document file: \(error.localizedDescription)"))
72
+ }
71
73
  }
72
- }
73
74
 
74
- func onError(error: Error) {
75
- product.onResult?(["error": error.localizedDescription])
76
- }
75
+ func onError(error: Error) {
76
+ smileIDUIViewDelegate.onError(error: error)
77
+ }
77
78
 
78
- func onSkip() {
79
- product.onResult?(["error": SmileIDError.unknown("SmileIDDocumentCaptureView skipped")])
80
- }
79
+ func onSkip() {
80
+ smileIDUIViewDelegate.onError(error: SmileIDError.unknown("SmileIDDocumentCaptureView skipped"))
81
+ }
81
82
  }
82
-
@@ -2,60 +2,61 @@ import Foundation
2
2
  import SmileID
3
3
  import SwiftUI
4
4
 
5
- struct SmileIDDocumentVerificationView: View ,SmileIDFileUtilsProtocol {
6
- var fileManager: FileManager = Foundation.FileManager.default
7
- @ObservedObject var product : SmileIDProductModel
8
- var body : some View {
9
- AnyView(NavigationView {
10
- if let countryCode = product.countryCode {
11
- SmileID.documentVerificationScreen(
12
- userId: product.userId ?? generateUserId(),
13
- jobId: product.jobId ?? generateJobId(),
14
- allowNewEnroll: product.allowNewEnroll,
15
- countryCode: countryCode, // already validated in SmileIDDocumentVerificationViewManager
16
- documentType: product.documentType,
17
- idAspectRatio: product.idAspectRatio,
18
- bypassSelfieCaptureWithFile: product.bypassSelfieCaptureWithFilePath,
19
- captureBothSides: product.captureBothSides,
20
- allowAgentMode: product.allowAgentMode,
21
- allowGalleryUpload: product.allowGalleryUpload,
22
- showInstructions: product.showInstructions,
23
- showAttribution: product.showAttribution,
24
- skipApiSubmission: product.skipApiSubmission,
25
- extraPartnerParams: product.extraPartnerParams as [String: String],
26
- delegate: self
27
- )
28
- } else {
29
- // This exists for debugging purposes and will show in extreme cases
30
- // when the params were not set NB: setParams in the viewmanager will always
31
- // return an error if the required data is missing
32
- Text("An error has occured")
33
- }
34
- }.navigationViewStyle(StackNavigationViewStyle()))
35
- }
5
+ struct SmileIDDocumentVerificationView: View, SmileIDFileUtilsProtocol {
6
+ var fileManager: FileManager = Foundation.FileManager.default
7
+ @ObservedObject var product: SmileIDProductModel
8
+ var smileIDUIViewDelegate: SmileIDUIViewDelegate
9
+ var body: some View {
10
+ AnyView(NavigationView {
11
+ if let countryCode = product.countryCode {
12
+ SmileID.documentVerificationScreen(
13
+ userId: product.userId ?? generateUserId(),
14
+ jobId: product.jobId ?? generateJobId(),
15
+ allowNewEnroll: product.allowNewEnroll,
16
+ countryCode: countryCode, // already validated in SmileIDDocumentVerificationViewManager
17
+ documentType: product.documentType,
18
+ idAspectRatio: product.idAspectRatio,
19
+ bypassSelfieCaptureWithFile: product.bypassSelfieCaptureWithFilePath,
20
+ captureBothSides: product.captureBothSides,
21
+ allowAgentMode: product.allowAgentMode,
22
+ allowGalleryUpload: product.allowGalleryUpload,
23
+ showInstructions: product.showInstructions,
24
+ showAttribution: product.showAttribution,
25
+ skipApiSubmission: product.skipApiSubmission,
26
+ useStrictMode: product.useStrictMode,
27
+ extraPartnerParams: product.extraPartnerParams as [String: String],
28
+ delegate: self
29
+ )
30
+ } else {
31
+ // This exists for debugging purposes and will show in extreme cases
32
+ // when the params were not set NB: setParams in the viewmanager will always
33
+ // return an error if the required data is missing
34
+ Text("An error has occured")
35
+ }
36
+ }.navigationViewStyle(StackNavigationViewStyle()))
37
+ }
36
38
  }
37
39
 
38
40
  extension SmileIDDocumentVerificationView: DocumentVerificationResultDelegate {
39
- func didSucceed(selfie: URL, documentFrontImage: URL, documentBackImage: URL?, didSubmitDocumentVerificationJob: Bool) {
40
-
41
- var params: [String: Any] = [
42
- "selfieFile": getFilePath(fileName: selfie.absoluteString),
43
- "documentFrontFile": getFilePath(fileName: documentFrontImage.absoluteString),
44
- "didSubmitDocumentVerificationJob": didSubmitDocumentVerificationJob
45
- ]
46
-
47
- if let documentBackImage = documentBackImage {
48
- params["documentBackFile"] = getFilePath(fileName: documentBackImage.absoluteString)
41
+ func didSucceed(selfie: URL, documentFrontImage: URL, documentBackImage: URL?, didSubmitDocumentVerificationJob: Bool) {
42
+ var params: [String: Any] = [
43
+ "selfieFile": getFilePath(fileName: selfie.absoluteString),
44
+ "documentFrontFile": getFilePath(fileName: documentFrontImage.absoluteString),
45
+ "didSubmitDocumentVerificationJob": didSubmitDocumentVerificationJob,
46
+ ]
47
+
48
+ if let documentBackImage = documentBackImage {
49
+ params["documentBackFile"] = getFilePath(fileName: documentBackImage.absoluteString)
50
+ }
51
+
52
+ guard let jsonData = try? JSONSerialization.data(withJSONObject: params.toJSONCompatibleDictionary(), options: .prettyPrinted) else {
53
+ smileIDUIViewDelegate.onError(error: SmileIDError.unknown("SmileIDDocumentVerificationView encoding error"))
54
+ return
55
+ }
56
+ smileIDUIViewDelegate.onResult(smileResult: String(data: jsonData, encoding: .utf8)!)
49
57
  }
50
-
51
- guard let jsonData = try? JSONSerialization.data(withJSONObject: params.toJSONCompatibleDictionary(), options: .prettyPrinted) else {
52
- product.onResult?(["error": SmileIDError.unknown("SmileIDDocumentVerificationView encoding error")])
53
- return
58
+
59
+ func didError(error: Error) {
60
+ smileIDUIViewDelegate.onError(error: error)
54
61
  }
55
- product.onResult?(["result": String(data: jsonData, encoding: .utf8)!])
56
- }
57
-
58
- func didError(error: Error) {
59
- product.onResult?(["error": error.localizedDescription])
60
- }
61
62
  }