Skip to content

Commit

Permalink
Enhanced Biometric Flow (#129)
Browse files Browse the repository at this point in the history
* added flutter enhanced biometric views

* added kotlin enhanced biometric views

* use new enhanced views

* bump up version and added changelog

* added todos

* setting up swift views v2

* updated swift interfaces

* updated deps

* fixed imports

* updated snapshot release on android

* added missing swift bindings

* updated the enhanced swift plugins

* updated the enhanced kotlin plugins

* updated to enhanced screens

* added response mapping

* updated gradle config to gradle plugins

* updated changelog

* migrate to kotlin 2.0

* updated changelog

* updated to android version 10.4.0

* updated changelog

* setting up ios

* disable swift plugin

* updated changelog
  • Loading branch information
jumaallan authored Dec 13, 2024
1 parent a639f6d commit 87c4e27
Show file tree
Hide file tree
Showing 26 changed files with 762 additions and 143 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Release Notes

## 10.3.0

* Introduce screens for the new Enhanced Selfie Capture Enrollment and Authentication Products (Android).
* Migrate to Gradle Plugin setup
* Update to Kotlin 2.0
* Bump android to 10.4.0 (https://github.com/smileidentity/android/releases/tag/v10.4.0)
* Bump iOS to 10.3.1 (https://github.com/smileidentity/ios/releases/tag/v10.3.1)

## 10.2.1

* Allow skipApiSubmission which will capture Enrollment, Authentication, Doc V and Enhanced DocV
Expand Down
40 changes: 29 additions & 11 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,34 +1,50 @@
group "com.smileidentity.flutter"
version findProperty("SDK_VERSION") ?: "10.3.7"
def kotlinVersion = findProperty('kotlinVersion') ?: '2.1.0'
def smileVersion = findProperty('smileVersion') ?: '10.4.0'
def kotlinCompilerExtension = findProperty('kotlinCompilerExtensionVersion') ?: '1.5.14'

ext {
project.ext.kotlinVersion = kotlinVersion
project.ext.smileVersion = smileVersion
project.ext.kotlinCompilerExtension = kotlinCompilerExtension
}

buildscript {
ext.kotlin_version = "1.9.10"
def kotlinVersion = rootProject.findProperty('kotlinVersion') ?: '2.1.0'

repositories {
google()
mavenCentral()
maven { url "https://plugins.gradle.org/m2/" }
}

dependencies {
classpath "com.android.tools.build:gradle:8.7.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jlleitschuh.gradle:ktlint-gradle:12.1.1"
classpath "com.android.tools.build:gradle:8.7.3"
if (kotlinVersion?.startsWith("2")) {
classpath "org.jetbrains.kotlin:compose-compiler-gradle-plugin:$kotlinVersion"
} else {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
}
classpath "org.jlleitschuh.gradle:ktlint-gradle:12.1.2"
}
}

allprojects {
repositories {
google()
mavenCentral()
maven {url "https://oss.sonatype.org/content/repositories/snapshots/com/smileidentity/android-sdk/" }
}
}

apply plugin: "com.android.library"
apply plugin: "kotlin-android"
apply plugin: "org.jlleitschuh.gradle.ktlint"
if (kotlinVersion?.startsWith("2")) {
apply plugin: "org.jetbrains.kotlin.plugin.compose"
}

android {
namespace group
namespace 'com.smileidentity.flutter'
compileSdk 35

defaultConfig {
Expand Down Expand Up @@ -61,19 +77,21 @@ android {
}

buildFeatures.compose = true
composeOptions {
kotlinCompilerExtensionVersion = "1.5.3"
if (!kotlinVersion?.startsWith("2")) {
composeOptions {
kotlinCompilerExtensionVersion = kotlinCompilerExtension
}
}

dependencies {
implementation "com.smileidentity:android-sdk:${version}"
implementation "com.smileidentity:android-sdk:${smileVersion}"
implementation "androidx.core:core-ktx"
implementation "androidx.compose.ui:ui"
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose'
implementation "androidx.compose.material3:material3"
implementation "androidx.fragment:fragment-ktx"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core"
implementation "org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.6"
implementation "org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.8"

testImplementation "org.jetbrains.kotlin:kotlin-test"
testImplementation "io.mockk:mockk:1.13.11"
Expand Down
2 changes: 1 addition & 1 deletion android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<manifest package="com.smileidentity.flutter" />
<manifest />
12 changes: 12 additions & 0 deletions android/src/main/kotlin/com/smileidentity/flutter/SmileIDPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import android.app.Activity
import android.content.Context
import com.smileidentity.SmileID
import com.smileidentity.SmileIDOptIn
import com.smileidentity.flutter.enhanced.SmileIDSmartSelfieAuthenticationEnhanced
import com.smileidentity.flutter.enhanced.SmileIDSmartSelfieEnrollmentEnhanced
import com.smileidentity.networking.asFormDataPart
import com.smileidentity.networking.pollBiometricKycJobStatus
import com.smileidentity.networking.pollDocumentVerificationJobStatus
Expand Down Expand Up @@ -72,6 +74,16 @@ class SmileIDPlugin :
SmileIDSmartSelfieAuthentication.Factory(flutterPluginBinding.binaryMessenger),
)

flutterPluginBinding.platformViewRegistry.registerViewFactory(
SmileIDSmartSelfieEnrollmentEnhanced.VIEW_TYPE_ID,
SmileIDSmartSelfieEnrollmentEnhanced.Factory(flutterPluginBinding.binaryMessenger),
)

flutterPluginBinding.platformViewRegistry.registerViewFactory(
SmileIDSmartSelfieAuthenticationEnhanced.VIEW_TYPE_ID,
SmileIDSmartSelfieAuthenticationEnhanced.Factory(flutterPluginBinding.binaryMessenger),
)

flutterPluginBinding.platformViewRegistry.registerViewFactory(
SmileIDBiometricKYC.VIEW_TYPE_ID,
SmileIDBiometricKYC.Factory(flutterPluginBinding.binaryMessenger),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.smileidentity.flutter.enhanced

import android.content.Context
import androidx.compose.runtime.Composable
import com.smileidentity.SmileID
import com.smileidentity.SmileID.moshi
import com.smileidentity.compose.SmartSelfieAuthenticationEnhanced
import com.smileidentity.flutter.SmileComposablePlatformView
import com.smileidentity.results.SmartSelfieResult
import com.smileidentity.results.SmileIDResult
import com.smileidentity.util.randomUserId
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 kotlinx.collections.immutable.toImmutableMap

internal class SmileIDSmartSelfieAuthenticationEnhanced private constructor(
context: Context,
viewId: Int,
messenger: BinaryMessenger,
args: Map<String, Any?>,
) : SmileComposablePlatformView(context, VIEW_TYPE_ID, viewId, messenger, args) {
companion object {
const val VIEW_TYPE_ID = "SmileIDSmartSelfieAuthenticationEnhanced"
}

@Composable
override fun Content(args: Map<String, Any?>) {
val extraPartnerParams = args["extraPartnerParams"] as? Map<String, String> ?: emptyMap()
SmileID.SmartSelfieAuthenticationEnhanced(
userId = args["userId"] as? String ?: randomUserId(),
allowNewEnroll = args["allowNewEnroll"] as? Boolean ?: false,
showAttribution = args["showAttribution"] as? Boolean ?: true,
showInstructions = args["showInstructions"] as? Boolean ?: true,
extraPartnerParams = extraPartnerParams.toImmutableMap(),
) {
when (it) {
is SmileIDResult.Success -> {
val result =
SmartSelfieResult(
selfieFile = it.data.selfieFile,
livenessFiles = it.data.livenessFiles,
apiResponse = it.data.apiResponse,
)
val json =
try {
moshi
.adapter(SmartSelfieResult::class.java)
.toJson(result)
} catch (e: Exception) {
onError(e)
return@SmartSelfieAuthenticationEnhanced
}
json?.let { response ->
onSuccessJson(response)
}
}

is SmileIDResult.Error -> onError(it.throwable)
}
}
}

class Factory(
private val messenger: BinaryMessenger,
) : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
override fun create(
context: Context,
viewId: Int,
args: Any?,
): PlatformView {
@Suppress("UNCHECKED_CAST")
return SmileIDSmartSelfieAuthenticationEnhanced(
context,
viewId,
messenger,
args as Map<String, Any?>,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.smileidentity.flutter.enhanced

import android.content.Context
import androidx.compose.runtime.Composable
import com.smileidentity.SmileID
import com.smileidentity.SmileID.moshi
import com.smileidentity.compose.SmartSelfieEnrollmentEnhanced
import com.smileidentity.flutter.SmileComposablePlatformView
import com.smileidentity.results.SmartSelfieResult
import com.smileidentity.results.SmileIDResult
import com.smileidentity.util.randomUserId
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 kotlinx.collections.immutable.toImmutableMap

internal class SmileIDSmartSelfieEnrollmentEnhanced private constructor(
context: Context,
viewId: Int,
messenger: BinaryMessenger,
args: Map<String, Any?>,
) : SmileComposablePlatformView(context, VIEW_TYPE_ID, viewId, messenger, args) {
companion object {
const val VIEW_TYPE_ID = "SmileIDSmartSelfieEnrollmentEnhanced"
}

@Composable
override fun Content(args: Map<String, Any?>) {
val extraPartnerParams = args["extraPartnerParams"] as? Map<String, String> ?: emptyMap()
SmileID.SmartSelfieEnrollmentEnhanced(
userId = args["userId"] as? String ?: randomUserId(),
allowNewEnroll = args["allowNewEnroll"] as? Boolean ?: false,
showAttribution = args["showAttribution"] as? Boolean ?: true,
showInstructions = args["showInstructions"] as? Boolean ?: true,
extraPartnerParams = extraPartnerParams.toImmutableMap(),
) {
when (it) {
is SmileIDResult.Success -> {
val result =
SmartSelfieResult(
selfieFile = it.data.selfieFile,
livenessFiles = it.data.livenessFiles,
apiResponse = it.data.apiResponse,
)
val json =
try {
moshi
.adapter(SmartSelfieResult::class.java)
.toJson(result)
} catch (e: Exception) {
onError(e)
return@SmartSelfieEnrollmentEnhanced
}
json?.let { response ->
onSuccessJson(response)
}
}

is SmileIDResult.Error -> onError(it.throwable)
}
}
}

class Factory(
private val messenger: BinaryMessenger,
) : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
override fun create(
context: Context,
viewId: Int,
args: Any?,
): PlatformView {
@Suppress("UNCHECKED_CAST")
return SmileIDSmartSelfieEnrollmentEnhanced(
context,
viewId,
messenger,
args as Map<String, Any?>,
)
}
}
}
45 changes: 8 additions & 37 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,31 +1,10 @@
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
plugins {
id "com.android.application"
id "kotlin-android"
id "org.jlleitschuh.gradle.ktlint"
id "dev.flutter.flutter-gradle-plugin"
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: "org.jlleitschuh.gradle.ktlint"

android {
namespace "com.smileidentity.flutter.sample"
compileSdk 35
Expand All @@ -38,8 +17,8 @@ android {
applicationId "com.smileidentity.flutter.sample"
minSdk 21
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
versionCode 1
versionName "1.0.0"
}

buildTypes {
Expand All @@ -52,12 +31,4 @@ android {
kotlinOptions {
jvmTarget = '17'
}
}

flutter {
source '../..'
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
}
Loading

0 comments on commit 87c4e27

Please sign in to comment.