From bcfe7dd8a892c05e9e915a0564bf51414b4a4126 Mon Sep 17 00:00:00 2001 From: JNdhlovu Date: Wed, 20 Nov 2024 14:03:40 +0200 Subject: [PATCH] feat: consistent file paths (#122) * feat: consistent file paths * feat: consistent file paths * feat: consistent file paths * fix: lint * fix: lint * fix: lint * feat: lint * downgrade native android * feat: lint * feat: pr feedback * feat: android kotlin fixed version * chore: bump version to 10.2.1 and update changelog * chore: remove snapshots * feature: bump target sdk to version to 35 --- CHANGELOG.md | 42 +++++++--- android/build.gradle | 2 +- .../flutter/SmileIDBiometricKYC.kt | 29 ++++++- .../flutter/SmileIDDocumentCaptureView.kt | 15 +--- .../flutter/SmileIDDocumentVerification.kt | 35 +++++++- .../SmileIDEnhancedDocumentVerification.kt | 32 +++++++- .../SmileIDSmartSelfieAuthentication.kt | 30 ++++++- .../flutter/SmileIDSmartSelfieCaptureView.kt | 12 +-- .../flutter/SmileIDSmartSelfieEnrollment.kt | 30 ++++++- .../flutter/results/DocumentCaptureResult.kt | 12 +++ .../results/SmartSelfieCaptureResult.kt | 10 +++ .../utils/DocumentCaptureResultAdapter.kt | 55 +++++++++++-- .../utils/SelfieCaptureResultAdapter.kt | 60 +++++++++----- example/android/app/build.gradle | 6 +- example/android/build.gradle | 2 + example/ios/Podfile.lock | 12 +-- example/pubspec.lock | 82 +++++++++++-------- ios/Classes/FileUtils.swift | 24 ++++++ ios/Classes/SmileIDBiometricKYC.swift | 12 +-- ios/Classes/SmileIDDictExt.swift | 30 +++++++ ios/Classes/SmileIDDocumentCaptureView.swift | 3 +- ios/Classes/SmileIDDocumentVerification.swift | 10 +-- .../SmileIDEnhancedDocumentVerification.swift | 10 +-- .../SmileIDSmartSelfieAuthentication.swift | 11 ++- .../SmileIDSmartSelfieCaptureView.swift | 3 +- .../SmileIDSmartSelfieEnrollment.swift | 11 ++- ios/smile_id.podspec | 18 ++-- lib/smile_id_document_verification.dart | 2 + ...ile_id_enhanced_document_verification.dart | 2 + lib/smile_id_smart_selfie_authentication.dart | 2 + lib/smile_id_smart_selfie_enrollment.dart | 2 + pubspec.yaml | 2 +- 32 files changed, 466 insertions(+), 142 deletions(-) create mode 100644 android/src/main/kotlin/com/smileidentity/flutter/results/DocumentCaptureResult.kt create mode 100644 android/src/main/kotlin/com/smileidentity/flutter/results/SmartSelfieCaptureResult.kt create mode 100644 ios/Classes/FileUtils.swift create mode 100644 ios/Classes/SmileIDDictExt.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e1d70e..b1e1bf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,21 +1,34 @@ # Release Notes +## 10.2.1 + +* Allow skipApiSubmission which will capture Enrollment, Authentication, Doc V and Enhanced DocV + without submitting to SmileID and will return captured images file paths +* Fix Consistent file paths for all products and capture screens +* Bump android to 10.3.7 (https://github.com/smileidentity/android/releases/tag/v10.3.7) +* Bump iOS to 10.2.17 (https://github.com/smileidentity/ios/releases/tag/v10.2.17) + ## 10.2.0 + * Remove `jobId` in selfie jobs. This is now passed inside `extraPartnerParams` ## 10.1.10 + * Added selfie capture screens * Added document capture screens * Bump iOS to 10.2.12 (https://github.com/smileidentity/ios/releases/tag/v10.2.12) * Update AGP versions -## 10.1.9 +## 10.1.9 + * Bump Android to 10.3.1 (https://github.com/smileidentity/android/releases/tag/v10.3.1) * Bump iOS to 10.2.10 (https://github.com/smileidentity/ios/releases/tag/v10.2.10) ## 10.1.8 + * Fix API Config to provide different options to configure SmileID -* Bump ios to 10.2.8 (https://github.com/smileidentity/ios/releases/tag/v10.2.8) In memory zip file handling +* Bump ios to 10.2.8 (https://github.com/smileidentity/ios/releases/tag/v10.2.8) In memory zip file + handling ## 10.1.7 @@ -33,11 +46,12 @@ ## 10.1.5 -* Fix navigation issue on iOS Flutter app +* Fix navigation issue on iOS Flutter app ## 10.1.4 -* Bump iOS to 10.2.2 (https://github.com/smileidentity/ios/releases/tag/v10.2.2) which fixes retry crash) +* Bump iOS to 10.2.2 (https://github.com/smileidentity/ios/releases/tag/v10.2.2) which fixes retry + crash) ## 10.1.3 @@ -54,13 +68,15 @@ ## 10.1.0 -* Moved SmartSelfie enrollment and authentication to synchronous endpoints +* Moved SmartSelfie enrollment and authentication to synchronous endpoints * Introduced polling methods for products - * SmartSelfie + * SmartSelfie * Biometric kyc * Document verification * Enhanced document verification -* Added an Offline Mode, enabled by calling `SmileID.setAllowOfflineMode(true)`. If a job is attempted while the device is offline, and offline mode has been enabled, the UI will complete successfully and the job can be submitted at a later time by calling `SmileID.submitJob(jobId)` +* Added an Offline Mode, enabled by calling `SmileID.setAllowOfflineMode(true)`. If a job is + attempted while the device is offline, and offline mode has been enabled, the UI will complete + successfully and the job can be submitted at a later time by calling `SmileID.submitJob(jobId)` * Improved SmartSelfie Enrollment and Authentication times by moving to a synchronous API endpoint * Update generic errors with actual platform errors * Bump iOS to 10.1.6 (https://github.com/smileidentity/ios/releases/tag/v10.1.6) @@ -68,7 +84,8 @@ ## 10.0.12 -* Fixed a bug where SmartSelfieEnrollment and SmartSelfieAuthentication would return invalid `livenessImages` in `onSuccess` +* Fixed a bug where SmartSelfieEnrollment and SmartSelfieAuthentication would return invalid + `livenessImages` in `onSuccess` ## 10.0.11 @@ -94,12 +111,14 @@ ## 10.0.6 -* Fixed a bug where Android builds would not compile when the partner app (or a library they consume) also uses `Pigeon` under the hood +* Fixed a bug where Android builds would not compile when the partner app (or a library they + consume) also uses `Pigeon` under the hood * Updated generated files naming to prefix `SmileID` and prevent build duplicate class erros ## 10.0.5 -* Fixed a bug where Android builds would not compile when the partner app (or a library they consume) also uses `Pigeon` under the hood +* Fixed a bug where Android builds would not compile when the partner app (or a library they + consume) also uses `Pigeon` under the hood * Bumped Android and iOS versions ## 10.0.4 @@ -147,7 +166,8 @@ * \[Android] Added `extras` as optional params on all job types * \[Android] Added `idAuthorityBypassPhoto` on Sandbox BiometricKYC jobs -* \[Android] Added `allowAgentMode` option on Document Verification and Enhanced Document Verification +* \[Android] Added `allowAgentMode` option on Document Verification and Enhanced Document + Verification * \[Flutter] Fixed wrong iOS decoding bug on success ## 10.0.0-beta05 diff --git a/android/build.gradle b/android/build.gradle index f28f94b..04a1f79 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -29,7 +29,7 @@ apply plugin: "org.jlleitschuh.gradle.ktlint" android { namespace group - compileSdk 34 + compileSdk 35 defaultConfig { minSdk 21 diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDBiometricKYC.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDBiometricKYC.kt index df891bb..aa7fa50 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDBiometricKYC.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDBiometricKYC.kt @@ -4,6 +4,8 @@ import android.content.Context import androidx.compose.runtime.Composable import com.smileidentity.SmileID import com.smileidentity.compose.BiometricKYC +import com.smileidentity.flutter.results.SmartSelfieCaptureResult +import com.smileidentity.flutter.utils.SelfieCaptureResultAdapter import com.smileidentity.models.IdInfo import com.smileidentity.results.SmileIDResult import com.smileidentity.util.randomJobId @@ -49,7 +51,32 @@ internal class SmileIDBiometricKYC private constructor( extraPartnerParams = extraPartnerParams.toImmutableMap(), ) { when (it) { - is SmileIDResult.Success -> onSuccess(it.data) + is SmileIDResult.Success -> { + val result = + SmartSelfieCaptureResult( + selfieFile = it.data.selfieFile, + livenessFiles = it.data.livenessFiles, + didSubmitBiometricKycJob = it.data.didSubmitBiometricKycJob, + ) + val moshi = + SmileID.moshi + .newBuilder() + .add(SelfieCaptureResultAdapter.FACTORY) + .build() + val json = + try { + moshi + .adapter(SmartSelfieCaptureResult::class.java) + .toJson(result) + } catch (e: Exception) { + onError(e) + return@BiometricKYC + } + json?.let { js -> + onSuccessJson(js) + } + } + is SmileIDResult.Error -> onError(it.throwable) } } diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentCaptureView.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentCaptureView.kt index 512e302..e7fda34 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentCaptureView.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentCaptureView.kt @@ -17,6 +17,7 @@ import com.smileidentity.compose.document.DocumentCaptureScreen import com.smileidentity.compose.document.DocumentCaptureSide import com.smileidentity.compose.theme.colorScheme import com.smileidentity.compose.theme.typography +import com.smileidentity.flutter.results.DocumentCaptureResult import com.smileidentity.flutter.utils.DocumentCaptureResultAdapter import com.smileidentity.models.v2.Metadata import com.smileidentity.util.randomJobId @@ -26,11 +27,6 @@ import io.flutter.plugin.platform.PlatformView import io.flutter.plugin.platform.PlatformViewFactory import java.io.File -data class DocumentCaptureResult( - val documentFrontFile: File? = null, - val documentBackFile: File? = null, -) - internal class SmileIDDocumentCaptureView private constructor( context: Context, viewId: Int, @@ -111,19 +107,10 @@ internal class SmileIDDocumentCaptureView private constructor( modifier = Modifier.fillMaxSize(), jobId = jobId, side = if (isDocumentFrontSide) DocumentCaptureSide.Front else DocumentCaptureSide.Back, - showInstructions = showInstructions, - showAttribution = showAttribution, - allowGallerySelection = allowGalleryUpload, - showSkipButton = false, - instructionsHeroImage = hero, - showConfirmation = showConfirmationDialog, - instructionsTitleText = stringResource(instructionTitle), - instructionsSubtitleText = stringResource(instructionSubTitle), captureTitleText = stringResource(captureTitleText), knownIdAspectRatio = idAspectRatio, onConfirm = { file -> handleConfirmation(isDocumentFrontSide, file) }, onError = { throwable -> onError(throwable) }, - onSkip = { }, ) } diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt index 88c77eb..776bc01 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDDocumentVerification.kt @@ -4,6 +4,8 @@ import android.content.Context import androidx.compose.runtime.Composable import com.smileidentity.SmileID import com.smileidentity.compose.DocumentVerification +import com.smileidentity.flutter.results.DocumentCaptureResult +import com.smileidentity.flutter.utils.DocumentCaptureResultAdapter import com.smileidentity.results.SmileIDResult import com.smileidentity.util.randomJobId import com.smileidentity.util.randomUserId @@ -33,7 +35,9 @@ internal class SmileIDDocumentVerification private constructor( idAspectRatio = (args["idAspectRatio"] as Double?)?.toFloat(), captureBothSides = args["captureBothSides"] as? Boolean ?: true, bypassSelfieCaptureWithFile = - (args["bypassSelfieCaptureWithFile"] as? String)?.let { File(it) }, + (args["bypassSelfieCaptureWithFile"] as? String)?.let { + File(it) + }, userId = args["userId"] as? String ?: randomUserId(), jobId = args["jobId"] as? String ?: randomJobId(), allowNewEnroll = args["allowNewEnroll"] as? Boolean ?: false, @@ -41,10 +45,37 @@ internal class SmileIDDocumentVerification private constructor( allowAgentMode = args["allowAgentMode"] as? Boolean ?: false, allowGalleryUpload = args["allowGalleryUpload"] as? Boolean ?: false, showInstructions = args["showInstructions"] as? Boolean ?: true, + skipApiSubmission = args["skipApiSubmission"] as? Boolean ?: false, extraPartnerParams = extraPartnerParams.toImmutableMap(), ) { when (it) { - is SmileIDResult.Success -> onSuccess(it.data) + is SmileIDResult.Success -> { + val result = + DocumentCaptureResult( + selfieFile = it.data.selfieFile, + documentFrontFile = it.data.documentFrontFile, + livenessFiles = it.data.livenessFiles, + documentBackFile = it.data.documentBackFile, + didSubmitDocumentVerificationJob = + it.data.didSubmitDocumentVerificationJob, + ) + val moshi = + SmileID.moshi + .newBuilder() + .add(DocumentCaptureResultAdapter.FACTORY) + .build() + val json = + try { + moshi.adapter(DocumentCaptureResult::class.java).toJson(result) + } catch (e: Exception) { + onError(e) + return@DocumentVerification + } + json?.let { js -> + onSuccessJson(js) + } + } + is SmileIDResult.Error -> onError(it.throwable) } } diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDEnhancedDocumentVerification.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDEnhancedDocumentVerification.kt index 27506b3..8130375 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDEnhancedDocumentVerification.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDEnhancedDocumentVerification.kt @@ -4,6 +4,8 @@ import android.content.Context import androidx.compose.runtime.Composable import com.smileidentity.SmileID import com.smileidentity.compose.EnhancedDocumentVerificationScreen +import com.smileidentity.flutter.results.DocumentCaptureResult +import com.smileidentity.flutter.utils.DocumentCaptureResultAdapter import com.smileidentity.results.SmileIDResult import com.smileidentity.util.randomJobId import com.smileidentity.util.randomUserId @@ -38,10 +40,38 @@ internal class SmileIDEnhancedDocumentVerification private constructor( allowAgentMode = args["allowAgentMode"] as? Boolean ?: false, allowGalleryUpload = args["allowGalleryUpload"] as? Boolean ?: false, showInstructions = args["showInstructions"] as? Boolean ?: true, + skipApiSubmission = args["skipApiSubmission"] as? Boolean ?: false, extraPartnerParams = extraPartnerParams.toImmutableMap(), ) { when (it) { - is SmileIDResult.Success -> onSuccess(it.data) + is SmileIDResult.Success -> { + val result = + DocumentCaptureResult( + selfieFile = it.data.selfieFile, + documentFrontFile = it.data.documentFrontFile, + livenessFiles = it.data.livenessFiles, + documentBackFile = it.data.documentBackFile, + didSubmitEnhancedDocVJob = it.data.didSubmitEnhancedDocVJob, + ) + val moshi = + SmileID.moshi + .newBuilder() + .add(DocumentCaptureResultAdapter.FACTORY) + .build() + val json = + try { + moshi + .adapter(DocumentCaptureResult::class.java) + .toJson(result) + } catch (e: Exception) { + onError(e) + return@EnhancedDocumentVerificationScreen + } + json?.let { js -> + onSuccessJson(js) + } + } + is SmileIDResult.Error -> onError(it.throwable) } } diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDSmartSelfieAuthentication.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDSmartSelfieAuthentication.kt index 4479837..5ed0a53 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDSmartSelfieAuthentication.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDSmartSelfieAuthentication.kt @@ -4,6 +4,8 @@ import android.content.Context import androidx.compose.runtime.Composable import com.smileidentity.SmileID import com.smileidentity.compose.SmartSelfieAuthentication +import com.smileidentity.flutter.results.SmartSelfieCaptureResult +import com.smileidentity.flutter.utils.SelfieCaptureResultAdapter import com.smileidentity.results.SmileIDResult import com.smileidentity.util.randomUserId import io.flutter.plugin.common.BinaryMessenger @@ -31,10 +33,36 @@ internal class SmileIDSmartSelfieAuthentication private constructor( allowAgentMode = args["allowAgentMode"] as? Boolean ?: false, showAttribution = args["showAttribution"] as? Boolean ?: true, showInstructions = args["showInstructions"] as? Boolean ?: true, + skipApiSubmission = args["skipApiSubmission"] as? Boolean ?: false, extraPartnerParams = extraPartnerParams.toImmutableMap(), ) { when (it) { - is SmileIDResult.Success -> onSuccess(it.data) + is SmileIDResult.Success -> { + val result = + SmartSelfieCaptureResult( + selfieFile = it.data.selfieFile, + livenessFiles = it.data.livenessFiles, + apiResponse = it.data.apiResponse, + ) + val moshi = + SmileID.moshi + .newBuilder() + .add(SelfieCaptureResultAdapter.FACTORY) + .build() + val json = + try { + moshi + .adapter(SmartSelfieCaptureResult::class.java) + .toJson(result) + } catch (e: Exception) { + onError(e) + return@SmartSelfieAuthentication + } + json?.let { js -> + onSuccessJson(js) + } + } + is SmileIDResult.Error -> onError(it.throwable) } } diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDSmartSelfieCaptureView.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDSmartSelfieCaptureView.kt index ac962a6..382f83a 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDSmartSelfieCaptureView.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDSmartSelfieCaptureView.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.statusBars import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider @@ -36,6 +35,7 @@ import com.smileidentity.compose.selfie.SelfieCaptureScreen import com.smileidentity.compose.selfie.SmartSelfieInstructionsScreen import com.smileidentity.compose.theme.colorScheme import com.smileidentity.compose.theme.typography +import com.smileidentity.flutter.results.SmartSelfieCaptureResult import com.smileidentity.flutter.utils.SelfieCaptureResultAdapter import com.smileidentity.models.v2.Metadata import com.smileidentity.results.SmileIDResult @@ -48,12 +48,6 @@ import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.StandardMessageCodec import io.flutter.plugin.platform.PlatformView import io.flutter.plugin.platform.PlatformViewFactory -import java.io.File - -data class SmartSelfieCaptureResult( - val selfieFile: File? = null, - val livenessFiles: List? = null, -) internal class SmileIDSmartSelfieCaptureView private constructor( context: Context, @@ -192,14 +186,14 @@ internal class SmileIDSmartSelfieCaptureView private constructor( selfieFile = res.data.selfieFile, livenessFiles = res.data.livenessFiles, ) - val newMoshi = + val moshi = SmileID.moshi .newBuilder() .add(SelfieCaptureResultAdapter.FACTORY) .build() val json = try { - newMoshi + moshi .adapter(SmartSelfieCaptureResult::class.java) .toJson(result) } catch (e: Exception) { diff --git a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDSmartSelfieEnrollment.kt b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDSmartSelfieEnrollment.kt index 794a5f5..a422d4e 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/SmileIDSmartSelfieEnrollment.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/SmileIDSmartSelfieEnrollment.kt @@ -4,6 +4,8 @@ import android.content.Context import androidx.compose.runtime.Composable import com.smileidentity.SmileID import com.smileidentity.compose.SmartSelfieEnrollment +import com.smileidentity.flutter.results.SmartSelfieCaptureResult +import com.smileidentity.flutter.utils.SelfieCaptureResultAdapter import com.smileidentity.results.SmileIDResult import com.smileidentity.util.randomUserId import io.flutter.plugin.common.BinaryMessenger @@ -31,10 +33,36 @@ internal class SmileIDSmartSelfieEnrollment private constructor( allowAgentMode = args["allowAgentMode"] as? Boolean ?: false, showAttribution = args["showAttribution"] as? Boolean ?: true, showInstructions = args["showInstructions"] as? Boolean ?: true, + skipApiSubmission = args["skipApiSubmission"] as? Boolean ?: false, extraPartnerParams = extraPartnerParams.toImmutableMap(), ) { when (it) { - is SmileIDResult.Success -> onSuccess(it.data) + is SmileIDResult.Success -> { + val result = + SmartSelfieCaptureResult( + selfieFile = it.data.selfieFile, + livenessFiles = it.data.livenessFiles, + apiResponse = it.data.apiResponse, + ) + val moshi = + SmileID.moshi + .newBuilder() + .add(SelfieCaptureResultAdapter.FACTORY) + .build() + val json = + try { + moshi + .adapter(SmartSelfieCaptureResult::class.java) + .toJson(result) + } catch (e: Exception) { + onError(e) + return@SmartSelfieEnrollment + } + json?.let { js -> + onSuccessJson(js) + } + } + is SmileIDResult.Error -> onError(it.throwable) } } diff --git a/android/src/main/kotlin/com/smileidentity/flutter/results/DocumentCaptureResult.kt b/android/src/main/kotlin/com/smileidentity/flutter/results/DocumentCaptureResult.kt new file mode 100644 index 0000000..827befa --- /dev/null +++ b/android/src/main/kotlin/com/smileidentity/flutter/results/DocumentCaptureResult.kt @@ -0,0 +1,12 @@ +package com.smileidentity.flutter.results + +import java.io.File + +data class DocumentCaptureResult( + val selfieFile: File? = null, + val documentFrontFile: File? = null, + val livenessFiles: List? = null, + val documentBackFile: File? = null, + val didSubmitDocumentVerificationJob: Boolean? = null, + val didSubmitEnhancedDocVJob: Boolean? = null, +) diff --git a/android/src/main/kotlin/com/smileidentity/flutter/results/SmartSelfieCaptureResult.kt b/android/src/main/kotlin/com/smileidentity/flutter/results/SmartSelfieCaptureResult.kt new file mode 100644 index 0000000..5f0a3c6 --- /dev/null +++ b/android/src/main/kotlin/com/smileidentity/flutter/results/SmartSelfieCaptureResult.kt @@ -0,0 +1,10 @@ +package com.smileidentity.flutter.results +import com.smileidentity.models.v2.SmartSelfieResponse +import java.io.File + +data class SmartSelfieCaptureResult( + val selfieFile: File? = null, + val livenessFiles: List? = null, + val apiResponse: SmartSelfieResponse? = null, + val didSubmitBiometricKycJob: Boolean? = null, +) diff --git a/android/src/main/kotlin/com/smileidentity/flutter/utils/DocumentCaptureResultAdapter.kt b/android/src/main/kotlin/com/smileidentity/flutter/utils/DocumentCaptureResultAdapter.kt index 89a1f0e..d55a8af 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/utils/DocumentCaptureResultAdapter.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/utils/DocumentCaptureResultAdapter.kt @@ -1,5 +1,6 @@ package com.smileidentity.flutter.utils -import com.smileidentity.flutter.DocumentCaptureResult + +import com.smileidentity.flutter.results.DocumentCaptureResult import com.squareup.moshi.FromJson import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonReader @@ -13,17 +14,44 @@ class DocumentCaptureResultAdapter : JsonAdapter() { @FromJson override fun fromJson(reader: JsonReader): DocumentCaptureResult { reader.beginObject() + var selfieFile: File? = null var frontFile: File? = null var backFile: File? = null + var livenessFiles: MutableList? = null + var didSubmitDocumentVerificationJob: Boolean? = null + var didSubmitEnhancedDocVJob: Boolean? = null while (reader.hasNext()) { when (reader.nextName()) { + "selfieFile" -> selfieFile = reader.nextString()?.let { File(it) } "documentFrontFile" -> frontFile = reader.nextString()?.let { File(it) } "documentBackFile" -> backFile = reader.nextString()?.let { File(it) } + "livenessFiles" -> { + livenessFiles = mutableListOf() + reader.beginArray() + while (reader.hasNext()) { + reader.nextString()?.let { livenessFiles.add(File(it)) } + } + reader.endArray() + } + + "didSubmitDocumentVerificationJob" -> + didSubmitDocumentVerificationJob = + reader.nextBoolean() + + "didSubmitEnhancedDocVJob" -> didSubmitEnhancedDocVJob = reader.nextBoolean() else -> reader.skipValue() } } reader.endObject() - return DocumentCaptureResult(frontFile, backFile) + + return DocumentCaptureResult( + selfieFile = selfieFile, + documentFrontFile = frontFile, + documentBackFile = backFile, + livenessFiles = livenessFiles, + didSubmitDocumentVerificationJob = didSubmitDocumentVerificationJob, + didSubmitEnhancedDocVJob = didSubmitEnhancedDocVJob, + ) } @ToJson @@ -35,9 +63,28 @@ class DocumentCaptureResultAdapter : JsonAdapter() { writer.nullValue() return } + writer.beginObject() + writer.name("selfieFile").value(value.selfieFile?.absolutePath) writer.name("documentFrontFile").value(value.documentFrontFile?.absolutePath) writer.name("documentBackFile").value(value.documentBackFile?.absolutePath) + + writer.name("livenessFiles") + if (value.livenessFiles == null) { + writer.nullValue() + } else { + writer.beginArray() + for (file in value.livenessFiles) { + writer.value(file.absolutePath) + } + writer.endArray() + } + + writer + .name("didSubmitDocumentVerificationJob") + .value(value.didSubmitDocumentVerificationJob) + writer.name("didSubmitEnhancedDocVJob").value(value.didSubmitEnhancedDocVJob) + writer.endObject() } @@ -49,9 +96,7 @@ class DocumentCaptureResultAdapter : JsonAdapter() { annotations: Set, moshi: Moshi, ): JsonAdapter<*>? = - if (type == - DocumentCaptureResult::class.java - ) { + if (type == DocumentCaptureResult::class.java) { DocumentCaptureResultAdapter() } else { null diff --git a/android/src/main/kotlin/com/smileidentity/flutter/utils/SelfieCaptureResultAdapter.kt b/android/src/main/kotlin/com/smileidentity/flutter/utils/SelfieCaptureResultAdapter.kt index 3abe5dc..75b4659 100644 --- a/android/src/main/kotlin/com/smileidentity/flutter/utils/SelfieCaptureResultAdapter.kt +++ b/android/src/main/kotlin/com/smileidentity/flutter/utils/SelfieCaptureResultAdapter.kt @@ -1,14 +1,15 @@ package com.smileidentity.flutter.utils -import com.smileidentity.flutter.SmartSelfieCaptureResult +import com.smileidentity.SmileID +import com.smileidentity.flutter.results.SmartSelfieCaptureResult +import com.smileidentity.models.v2.SmartSelfieResponse import com.squareup.moshi.FromJson import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonAdapter.Factory import com.squareup.moshi.JsonReader import com.squareup.moshi.JsonWriter -import com.squareup.moshi.Moshi import com.squareup.moshi.ToJson import java.io.File -import java.lang.reflect.Type class SelfieCaptureResultAdapter : JsonAdapter() { @FromJson @@ -16,23 +17,36 @@ class SelfieCaptureResultAdapter : JsonAdapter() { reader.beginObject() var selfieFile: File? = null var livenessFiles: List? = null + var apiResponse: SmartSelfieResponse? = null + while (reader.hasNext()) { when (reader.nextName()) { "selfieFile" -> selfieFile = reader.nextString()?.let { File(it) } "livenessFiles" -> { - reader.beginArray() + // Assuming livenessFiles is an array of file paths in the JSON val files = mutableListOf() + reader.beginArray() while (reader.hasNext()) { reader.nextString()?.let { files.add(File(it)) } } reader.endArray() livenessFiles = files } + + "apiResponse" -> + apiResponse = + SmileID.moshi.adapter(SmartSelfieResponse::class.java).fromJson(reader) + else -> reader.skipValue() } } + reader.endObject() - return SmartSelfieCaptureResult(selfieFile, livenessFiles) + return SmartSelfieCaptureResult( + selfieFile = selfieFile, + livenessFiles = livenessFiles, + apiResponse = apiResponse, + ) } @ToJson @@ -46,30 +60,34 @@ class SelfieCaptureResultAdapter : JsonAdapter() { } writer.beginObject() writer.name("selfieFile").value(value.selfieFile?.absolutePath) + writer.name("livenessFiles") writer.beginArray() - value.livenessFiles?.forEach { file -> - writer.value(file.absolutePath) - } + value.livenessFiles?.forEach { writer.value(it.absolutePath) } writer.endArray() + + writer.name("apiResponse") + if (value.apiResponse != null) { + SmileID.moshi.adapter(SmartSelfieResponse::class.java).toJson( + writer, + value.apiResponse, + ) + } else { + writer.nullValue() + } writer.endObject() } companion object { val FACTORY = - object : Factory { - override fun create( - type: Type, - annotations: Set, - moshi: Moshi, - ): JsonAdapter<*>? = - if (type == - SmartSelfieCaptureResult::class.java - ) { - SelfieCaptureResultAdapter() - } else { - null - } + Factory { type, annotations, moshi -> + if (type == + SmartSelfieCaptureResult::class.java + ) { + SelfieCaptureResultAdapter() + } else { + null + } } } } diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index eaf3317..48af2b0 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -28,7 +28,7 @@ apply plugin: "org.jlleitschuh.gradle.ktlint" android { namespace "com.smileidentity.flutter.sample" - compileSdk 34 + compileSdk 35 sourceSets { main.java.srcDirs += 'src/main/kotlin' @@ -48,6 +48,10 @@ android { signingConfig signingConfigs.debug } } + + kotlinOptions { + jvmTarget = '17' + } } flutter { diff --git a/example/android/build.gradle b/example/android/build.gradle index 1c48bbf..a5dd824 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -6,6 +6,7 @@ buildscript { google() mavenCentral() maven { url "https://plugins.gradle.org/m2/" } + mavenCentral { url "https://oss.sonatype.org/content/repositories/snapshots" } } dependencies { @@ -19,6 +20,7 @@ allprojects { repositories { google() mavenCentral() + mavenCentral { url "https://oss.sonatype.org/content/repositories/snapshots" } } } diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 793da36..c11198b 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -8,10 +8,10 @@ PODS: - integration_test (0.0.1): - Flutter - lottie-ios (4.4.3) - - smile_id (10.2.14): + - smile_id (10.2.17): - Flutter - - SmileID (= 10.2.14) - - SmileID (10.2.14): + - SmileID (= 10.2.17) + - SmileID (10.2.17): - FingerprintJS - lottie-ios (~> 4.4.2) - ZIPFoundation (~> 0.9) @@ -40,10 +40,10 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: FingerprintJS: 96410117a394cca04d0f1e2374944c8697f2cceb Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 + integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4 lottie-ios: fcb5e73e17ba4c983140b7d21095c834b3087418 - smile_id: 3032fbe9028f83515a9f65b10f0ada419aec9860 - SmileID: 5b3315414026c4b3bc7dfb0e39ab48fe21299ec3 + smile_id: 093dedd19ea8c796492a1069702757408ac9a5d6 + SmileID: 44fef36001a02aa7362368e8a3f1127c03751166 ZIPFoundation: b8c29ea7ae353b309bc810586181fd073cb3312c PODFILE CHECKSUM: 929954fb8941cef06249e96bd1516fd2a22ed7a5 diff --git a/example/pubspec.lock b/example/pubspec.lock index dbb95c5..5c11cd0 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" cupertino_icons: dependency: "direct main" description: @@ -61,10 +61,10 @@ packages: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.0" flutter: dependency: "direct main" description: flutter @@ -98,14 +98,30 @@ packages: description: flutter source: sdk version: "0.0.0" - js: + leak_tracker: dependency: transitive description: - name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + name: leak_tracker + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" url: "https://pub.dev" source: hosted - version: "0.6.7" + version: "10.0.4" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + url: "https://pub.dev" + source: hosted + version: "3.0.3" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" lints: dependency: transitive description: @@ -118,42 +134,42 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.12.0" path: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" platform: dependency: transitive description: name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.4" plugin_platform_interface: dependency: transitive description: @@ -166,10 +182,10 @@ packages: dependency: transitive description: name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" url: "https://pub.dev" source: hosted - version: "4.2.4" + version: "5.0.2" sky_engine: dependency: transitive description: flutter @@ -181,7 +197,7 @@ packages: path: ".." relative: true source: path - version: "10.1.10" + version: "10.2.1" source_span: dependency: transitive description: @@ -194,18 +210,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" string_scanner: dependency: transitive description: @@ -234,10 +250,10 @@ packages: dependency: transitive description: name: test_api - sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.6.0" + version: "0.7.0" vector_math: dependency: transitive description: @@ -250,18 +266,18 @@ packages: dependency: transitive description: name: vm_service - sha256: f3743ca475e0c9ef71df4ba15eb2d7684eecd5c8ba20a462462e4e8b561b2e11 + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "11.6.0" + version: "14.2.1" webdriver: dependency: transitive description: name: webdriver - sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49" + sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" sdks: - dart: ">=3.0.5 <4.0.0" - flutter: ">=3.0.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/ios/Classes/FileUtils.swift b/ios/Classes/FileUtils.swift new file mode 100644 index 0000000..092a300 --- /dev/null +++ b/ios/Classes/FileUtils.swift @@ -0,0 +1,24 @@ +protocol SmileIDFileUtilsProtocol { + var fileManager: FileManager { get set } + func getFilePath(fileName: String) -> String +} + +extension SmileIDFileUtilsProtocol { + func getSmileIDDirectory() -> String? { + guard let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else { + print("Unable to access documents directory") + return nil + } + + let smileIDDirectory = documentsDirectory.appendingPathComponent("SmileID") + return smileIDDirectory.absoluteURL.absoluteString + } + + func getFilePath(fileName: String) -> String { + guard let smileIDDirectory = getSmileIDDirectory() else { + return "" + } + + return (smileIDDirectory as NSString).appendingPathComponent(fileName) + } +} diff --git a/ios/Classes/SmileIDBiometricKYC.swift b/ios/Classes/SmileIDBiometricKYC.swift index 9f22adc..0fc3915 100644 --- a/ios/Classes/SmileIDBiometricKYC.swift +++ b/ios/Classes/SmileIDBiometricKYC.swift @@ -3,8 +3,8 @@ import UIKit import SmileID import SwiftUI -class SmileIDBiometricKYC : NSObject, FlutterPlatformView, BiometricKycResultDelegate { - +class SmileIDBiometricKYC : NSObject, FlutterPlatformView, BiometricKycResultDelegate,SmileIDFileUtilsProtocol { + var fileManager: FileManager = Foundation.FileManager.default private var _view: UIView private var _channel: FlutterMethodChannel private var _childViewController: UIViewController? @@ -55,9 +55,11 @@ class SmileIDBiometricKYC : NSObject, FlutterPlatformView, BiometricKycResultDel func didSucceed(selfieImage: URL, livenessImages: [URL], didSubmitBiometricJob: Bool) { _childViewController?.removeFromParent() let arguments: [String: Any] = [ - "selfieFile": selfieImage.absoluteString, - "livenessFiles": livenessImages.map { $0.absoluteString }, - "didSubmitBiometricKycJob": didSubmitBiometricJob + "selfieFile": getFilePath(fileName: selfieImage.absoluteString), + "livenessFiles": livenessImages.map { + getFilePath(fileName: $0.absoluteString) + }, + "didSubmitBiometricKycJob": didSubmitBiometricJob, ] do { let jsonData = try JSONSerialization.data(withJSONObject: arguments, options: []) diff --git a/ios/Classes/SmileIDDictExt.swift b/ios/Classes/SmileIDDictExt.swift new file mode 100644 index 0000000..dfe4a87 --- /dev/null +++ b/ios/Classes/SmileIDDictExt.swift @@ -0,0 +1,30 @@ +extension Dictionary where Key == String, Value == Any { + func toJSONCompatibleDictionary() -> [String: Any] { + var jsonCompatibleDict = [String: Any]() + for (key, value) in self { + if let arrayValue = value as? [Any] { + jsonCompatibleDict[key] = arrayValue.map { convertToJSONCompatible($0) } + } else { + jsonCompatibleDict[key] = convertToJSONCompatible(value) + } + } + return jsonCompatibleDict + } + + private func convertToJSONCompatible(_ value: Any) -> Any { + switch value { + case let url as URL: + return url.absoluteString + case let bool as Bool: + return bool + case let string as String: + return string + case let number as NSNumber: + return number + case let dict as [String: Any]: + return dict.toJSONCompatibleDictionary() + default: + return String(describing: value) + } + } +} diff --git a/ios/Classes/SmileIDDocumentCaptureView.swift b/ios/Classes/SmileIDDocumentCaptureView.swift index e896bbf..52ace1f 100644 --- a/ios/Classes/SmileIDDocumentCaptureView.swift +++ b/ios/Classes/SmileIDDocumentCaptureView.swift @@ -3,7 +3,8 @@ import SwiftUI import Combine import SmileID -class SmileIDDocumentCaptureView: NSObject, FlutterPlatformView { +class SmileIDDocumentCaptureView: NSObject, FlutterPlatformView,SmileIDFileUtilsProtocol { + var fileManager: FileManager = Foundation.FileManager.default private let _childViewController: UIHostingController private let _channel: FlutterMethodChannel diff --git a/ios/Classes/SmileIDDocumentVerification.swift b/ios/Classes/SmileIDDocumentVerification.swift index d88c9f6..a895110 100644 --- a/ios/Classes/SmileIDDocumentVerification.swift +++ b/ios/Classes/SmileIDDocumentVerification.swift @@ -3,8 +3,8 @@ import UIKit import SmileID import SwiftUI -class SmileIDDocumentVerification : NSObject, FlutterPlatformView, DocumentVerificationResultDelegate { - +class SmileIDDocumentVerification : NSObject, FlutterPlatformView, DocumentVerificationResultDelegate,SmileIDFileUtilsProtocol { + var fileManager: FileManager = Foundation.FileManager.default private var _view: UIView private var _channel: FlutterMethodChannel private var _childViewController: UIViewController? @@ -39,6 +39,7 @@ class SmileIDDocumentVerification : NSObject, FlutterPlatformView, DocumentVerif allowGalleryUpload: args["allowGalleryUpload"] as? Bool ?? false, showInstructions: args["showInstructions"] as? Bool ?? true, showAttribution: args["showAttribution"] as? Bool ?? true, + skipApiSubmission: args["skipApiSubmission"] as? Bool ?? false, extraPartnerParams: args["extraPartnerParams"] as? [String: String] ?? [:], delegate: self ) @@ -52,9 +53,8 @@ class SmileIDDocumentVerification : NSObject, FlutterPlatformView, DocumentVerif func didSucceed(selfie: URL, documentFrontImage: URL, documentBackImage: URL?, didSubmitDocumentVerificationJob: Bool) { _childViewController?.removeFromParent() let arguments: [String: Any] = [ - "selfieFile": selfie.absoluteString, - "documentFrontFile": documentFrontImage.absoluteString, - "documentBackFile": documentBackImage?.absoluteString ?? "", + "selfieFile": getFilePath(fileName: selfie.absoluteString), + "documentFrontFile": getFilePath(fileName: documentFrontImage.absoluteString), "didSubmitDocumentVerificationJob": didSubmitDocumentVerificationJob ] do { diff --git a/ios/Classes/SmileIDEnhancedDocumentVerification.swift b/ios/Classes/SmileIDEnhancedDocumentVerification.swift index b3a3954..41d7e14 100644 --- a/ios/Classes/SmileIDEnhancedDocumentVerification.swift +++ b/ios/Classes/SmileIDEnhancedDocumentVerification.swift @@ -3,8 +3,8 @@ import UIKit import SmileID import SwiftUI -class SmileIDEnhancedDocumentVerification : NSObject, FlutterPlatformView, EnhancedDocumentVerificationResultDelegate { - +class SmileIDEnhancedDocumentVerification : NSObject, FlutterPlatformView, EnhancedDocumentVerificationResultDelegate,SmileIDFileUtilsProtocol { + var fileManager: FileManager = Foundation.FileManager.default private var _view: UIView private var _channel: FlutterMethodChannel private var _childViewController: UIViewController? @@ -38,6 +38,7 @@ class SmileIDEnhancedDocumentVerification : NSObject, FlutterPlatformView, Enhan allowAgentMode: args["allowAgentMode"] as? Bool ?? false, allowGalleryUpload: args["allowGalleryUpload"] as? Bool ?? false, showInstructions: args["showInstructions"] as? Bool ?? true, + skipApiSubmission: args["skipApiSubmission"] as? Bool ?? false, showAttribution: args["showAttribution"] as? Bool ?? true, extraPartnerParams: args["extraPartnerParams"] as? [String: String] ?? [:], delegate: self @@ -52,9 +53,8 @@ class SmileIDEnhancedDocumentVerification : NSObject, FlutterPlatformView, Enhan func didSucceed(selfie: URL, documentFrontImage: URL, documentBackImage: URL?, didSubmitEnhancedDocVJob: Bool) { _childViewController?.removeFromParent() let arguments: [String: Any] = [ - "selfieFile": selfie.absoluteString, - "documentFrontFile": documentFrontImage.absoluteString, - "documentBackFile": documentBackImage?.absoluteString ?? "", + "selfieFile": getFilePath(fileName: selfie.absoluteString), + "documentFrontFile": getFilePath(fileName: documentFrontImage.absoluteString), "didSubmitEnhancedDocVJob": didSubmitEnhancedDocVJob ] do { diff --git a/ios/Classes/SmileIDSmartSelfieAuthentication.swift b/ios/Classes/SmileIDSmartSelfieAuthentication.swift index 8e2b553..0ab028c 100644 --- a/ios/Classes/SmileIDSmartSelfieAuthentication.swift +++ b/ios/Classes/SmileIDSmartSelfieAuthentication.swift @@ -3,8 +3,8 @@ import UIKit import SmileID import SwiftUI -class SmileIDSmartSelfieAuthentication : NSObject, FlutterPlatformView, SmartSelfieResultDelegate { - +class SmileIDSmartSelfieAuthentication : NSObject, FlutterPlatformView, SmartSelfieResultDelegate,SmileIDFileUtilsProtocol { + var fileManager: FileManager = Foundation.FileManager.default private var _view: UIView private var _channel: FlutterMethodChannel private var _childViewController: UIViewController? @@ -30,6 +30,7 @@ class SmileIDSmartSelfieAuthentication : NSObject, FlutterPlatformView, SmartSel allowAgentMode: args["allowAgentMode"] as? Bool ?? false, showAttribution: args["showAttribution"] as? Bool ?? true, showInstructions: args["showInstructions"] as? Bool ?? true, + skipApiSubmission: args["skipApiSubmission"] as? Bool ?? false, extraPartnerParams: args["extraPartnerParams"] as? [String: String] ?? [:], delegate: self ) @@ -43,8 +44,10 @@ class SmileIDSmartSelfieAuthentication : NSObject, FlutterPlatformView, SmartSel func didSucceed(selfieImage: URL, livenessImages: [URL], apiResponse: SmartSelfieResponse?) { _childViewController?.removeFromParent() var arguments: [String: Any] = [ - "selfieFile": selfieImage.absoluteString, - "livenessFiles": livenessImages.map { $0.absoluteString } + "selfieFile": getFilePath(fileName: selfieImage.absoluteString), + "livenessFiles": livenessImages.map { + getFilePath(fileName: $0.absoluteString) + }, ] if let apiResponse = apiResponse { let encoder = JSONEncoder() diff --git a/ios/Classes/SmileIDSmartSelfieCaptureView.swift b/ios/Classes/SmileIDSmartSelfieCaptureView.swift index 34cb201..7657288 100644 --- a/ios/Classes/SmileIDSmartSelfieCaptureView.swift +++ b/ios/Classes/SmileIDSmartSelfieCaptureView.swift @@ -3,7 +3,8 @@ import SwiftUI import Combine import SmileID -class SmileIDSmartSelfieCaptureView: NSObject, FlutterPlatformView { +class SmileIDSmartSelfieCaptureView: NSObject, FlutterPlatformView,SmileIDFileUtilsProtocol { + var fileManager: FileManager = Foundation.FileManager.default private let _childViewController: UIHostingController private let _viewModel: SelfieViewModel private let _channel: FlutterMethodChannel diff --git a/ios/Classes/SmileIDSmartSelfieEnrollment.swift b/ios/Classes/SmileIDSmartSelfieEnrollment.swift index 54263e9..546f6f8 100644 --- a/ios/Classes/SmileIDSmartSelfieEnrollment.swift +++ b/ios/Classes/SmileIDSmartSelfieEnrollment.swift @@ -3,8 +3,8 @@ import UIKit import SmileID import SwiftUI -class SmileIDSmartSelfieEnrollment : NSObject, FlutterPlatformView, SmartSelfieResultDelegate { - +class SmileIDSmartSelfieEnrollment : NSObject, FlutterPlatformView, SmartSelfieResultDelegate,SmileIDFileUtilsProtocol { + var fileManager: FileManager = Foundation.FileManager.default private var _view: UIView private var _channel: FlutterMethodChannel private var _childViewController: UIViewController? @@ -30,6 +30,7 @@ class SmileIDSmartSelfieEnrollment : NSObject, FlutterPlatformView, SmartSelfieR allowAgentMode: args["allowAgentMode"] as? Bool ?? false, showAttribution: args["showAttribution"] as? Bool ?? true, showInstructions: args["showInstructions"] as? Bool ?? true, + skipApiSubmission: args["skipApiSubmission"] as? Bool ?? false, extraPartnerParams: args["extraPartnerParams"] as? [String: String] ?? [:], delegate: self ) @@ -43,8 +44,10 @@ class SmileIDSmartSelfieEnrollment : NSObject, FlutterPlatformView, SmartSelfieR func didSucceed(selfieImage: URL, livenessImages: [URL], apiResponse: SmartSelfieResponse?) { _childViewController?.removeFromParent() var arguments: [String: Any] = [ - "selfieFile": selfieImage.absoluteString, - "livenessFiles": livenessImages.map { $0.absoluteString } + "selfieFile": getFilePath(fileName: selfieImage.absoluteString), + "livenessFiles": livenessImages.map { + getFilePath(fileName: $0.absoluteString) + } ] if let apiResponse = apiResponse { let encoder = JSONEncoder() diff --git a/ios/smile_id.podspec b/ios/smile_id.podspec index f40d89e..47f0210 100644 --- a/ios/smile_id.podspec +++ b/ios/smile_id.podspec @@ -2,20 +2,20 @@ # Run `pod lib lint smileid.podspec` to validate before publishing. # Pod::Spec.new do |s| - s.name = 'smile_id' + s.name = 'smile_id' # NB! Keep this version in sync with the Native iOS SDK version - s.version = '10.2.14' - s.summary = 'Official Smile ID SDK for Flutter' - s.description = <<-DESC + s.version = '10.2.17' + s.summary = 'Official Smile ID SDK for Flutter' + s.description = <<-DESC A new Flutter project. - DESC - s.homepage = 'http://usesmileid.com' - s.author = { 'Smile ID' => 'support@usesmileid.com' } - s.source = { :path => '.' } + DESC + s.homepage = 'http://usesmileid.com' + s.author = { 'Smile ID' => 'support@usesmileid.com' } + s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.dependency 'Flutter' # NB! Update the s.version above when changing this version - s.dependency 'SmileID', '10.2.14' + s.dependency 'SmileID', '10.2.17' s.platform = :ios, '13.0' # Flutter.framework does not contain a i386 slice. diff --git a/lib/smile_id_document_verification.dart b/lib/smile_id_document_verification.dart index acdcf33..c7e3f63 100644 --- a/lib/smile_id_document_verification.dart +++ b/lib/smile_id_document_verification.dart @@ -35,6 +35,7 @@ class SmileIDDocumentVerification extends StatelessWidget { bool allowGalleryUpload = false, bool allowAgentMode = false, bool showInstructions = true, + bool skipApiSubmission = false, Map? extraPartnerParams, required Function(String resultJson) onSuccess, required Function(String errorMessage) onError, @@ -55,6 +56,7 @@ class SmileIDDocumentVerification extends StatelessWidget { "allowAgentMode": allowAgentMode, "allowGalleryUpload": allowGalleryUpload, "showInstructions": showInstructions, + "skipApiSubmission" : skipApiSubmission, "extraPartnerParams" : extraPartnerParams, }, ); diff --git a/lib/smile_id_enhanced_document_verification.dart b/lib/smile_id_enhanced_document_verification.dart index 8487e30..ef96ea6 100644 --- a/lib/smile_id_enhanced_document_verification.dart +++ b/lib/smile_id_enhanced_document_verification.dart @@ -35,6 +35,7 @@ class SmileIDEnhancedDocumentVerification extends StatelessWidget { bool allowGalleryUpload = false, bool allowAgentMode = false, bool showInstructions = true, + bool skipApiSubmission = false, Map? extraPartnerParams, required Function(String resultJson) onSuccess, required Function(String errorMessage) onError, @@ -54,6 +55,7 @@ class SmileIDEnhancedDocumentVerification extends StatelessWidget { "allowAgentMode": allowAgentMode, "allowGalleryUpload": allowGalleryUpload, "showInstructions": showInstructions, + "skipApiSubmission" : skipApiSubmission, "extraPartnerParams" : extraPartnerParams, }, ); diff --git a/lib/smile_id_smart_selfie_authentication.dart b/lib/smile_id_smart_selfie_authentication.dart index c1d54fb..2d7655c 100644 --- a/lib/smile_id_smart_selfie_authentication.dart +++ b/lib/smile_id_smart_selfie_authentication.dart @@ -28,6 +28,7 @@ class SmileIDSmartSelfieAuthentication extends StatelessWidget { bool allowAgentMode = false, bool showAttribution = true, bool showInstructions = true, + bool skipApiSubmission = false, Map? extraPartnerParams, required Function(String resultJson) onSuccess, required Function(String errorMessage) onError, @@ -41,6 +42,7 @@ class SmileIDSmartSelfieAuthentication extends StatelessWidget { "allowAgentMode": allowAgentMode, "showAttribution": showAttribution, "showInstructions": showInstructions, + "skipApiSubmission" : skipApiSubmission, "extraPartnerParams" : extraPartnerParams, }, ); diff --git a/lib/smile_id_smart_selfie_enrollment.dart b/lib/smile_id_smart_selfie_enrollment.dart index 5ca4cbe..c310b28 100644 --- a/lib/smile_id_smart_selfie_enrollment.dart +++ b/lib/smile_id_smart_selfie_enrollment.dart @@ -28,6 +28,7 @@ class SmileIDSmartSelfieEnrollment extends StatelessWidget { bool allowAgentMode = false, bool showAttribution = true, bool showInstructions = true, + bool skipApiSubmission = false, Map? extraPartnerParams, required Function(String resultJson) onSuccess, required Function(String errorMessage) onError, @@ -42,6 +43,7 @@ class SmileIDSmartSelfieEnrollment extends StatelessWidget { "showAttribution": showAttribution, "showInstructions": showInstructions, "extraPartnerParams" : extraPartnerParams, + "skipApiSubmission" : skipApiSubmission, }, ); } diff --git a/pubspec.yaml b/pubspec.yaml index 781bbb9..08e1639 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: smile_id description: The Official Smile ID Flutter SDK -version: 10.2.0 +version: 10.2.1 homepage: "https://usesmileid.com" environment: