Skip to content

Commit 6eac045

Browse files
Release 5.0.0
1 parent 4fc0c35 commit 6eac045

File tree

12 files changed

+100
-66
lines changed

12 files changed

+100
-66
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# iProov Biometrics Flutter SDK
22

3+
## 5.0.0
4+
5+
iProov Biometrics Flutter SDK v5.0.0 includes the following changes
6+
7+
### iOS
8+
9+
* Upgraded SDK to [v12.0.0](https://github.com/iProov/ios/releases/tag/12.0.0).
10+
* Requires iOS 13 and above
11+
12+
### Android
13+
14+
* Upgraded SDK to [v10.0.0](https://github.com/iProov/android/releases/tag/v10.0.0).
15+
* Requires Android API Level 26 (Android 8 Oreo) and above
16+
17+
318
## 4.0.4
419

520
* Added `additionalOptions` parameter to `getToken()` in the Dart API client.

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ We also provide an API Client written in Dart to call our [REST API v2](https://
1111

1212
- Dart SDK 2.15 and above
1313
- Flutter SDK 1.20 and above
14-
- iOS 12 and above
15-
- Android API Level 21 (Android 5 Lollipop) and above
14+
- iOS 13 and above
15+
- Android API Level 26 (Android 8 Oreo) and above
1616

1717
## Repository contents
1818

@@ -35,7 +35,7 @@ Add the following to your project's `pubspec.yaml` file:
3535

3636
```yaml
3737
dependencies:
38-
iproov_flutter: ^4.0.3
38+
iproov_flutter: ^5.0.0
3939
```
4040
4141
You can then install it with:

android/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
group 'com.iproov.flutter_sdk_plugin'
2-
version '4.0.3'
2+
version '5.0.0'
33

44
buildscript {
55
ext.kotlin_version = '1.5.30'
@@ -32,7 +32,7 @@ android {
3232
main.java.srcDirs += 'src/main/kotlin'
3333
}
3434
defaultConfig {
35-
minSdkVersion 21
35+
minSdkVersion 26
3636
}
3737
lintOptions {
3838
disable 'InvalidPackage'
@@ -41,5 +41,5 @@ android {
4141

4242
dependencies {
4343
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
44-
implementation "com.iproov.sdk:iproov:9.1.1"
44+
implementation "com.iproov.sdk:iproov:10.0.0"
4545
}

android/src/main/kotlin/com/iproov/sdk/IProovSDKPlugin.kt

Lines changed: 56 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ package com.iproov.sdk
22

33
import android.content.Context
44
import android.graphics.Bitmap
5-
import com.iproov.sdk.bridge.OptionsBridge
6-
import com.iproov.sdk.core.exception.*
5+
import com.iproov.sdk.api.OptionsBridge
6+
import com.iproov.sdk.api.IProov
7+
import com.iproov.sdk.api.exception.*
78
import io.flutter.FlutterInjector
89
import io.flutter.embedding.engine.plugins.FlutterPlugin
910
import io.flutter.plugin.common.EventChannel
@@ -15,6 +16,8 @@ import kotlinx.coroutines.CoroutineScope
1516
import kotlinx.coroutines.Dispatchers
1617
import kotlinx.coroutines.SupervisorJob
1718
import kotlinx.coroutines.flow.collect
19+
import kotlinx.coroutines.flow.onSubscription
20+
import kotlinx.coroutines.Job
1821
import kotlinx.coroutines.launch
1922
import kotlinx.coroutines.cancel
2023
import kotlinx.coroutines.withContext
@@ -35,30 +38,29 @@ class IProovSDKPlugin : FlutterPlugin {
3538
private var eventSink: EventChannel.EventSink? = null
3639
private var uiEventSink: EventChannel.EventSink? = null
3740
private var flutterPluginBinding: FlutterPlugin.FlutterPluginBinding? = null
38-
private val launcher = IProovFlowLauncher()
39-
private var pendingException: IProovException? = null
4041

41-
init {
42-
sessionStateListener()
43-
sessionUIStateListener()
44-
}
42+
private var sessionStateJob: Job? = null
43+
private var sessionUIStateJob: Job? = null
44+
private var pendingException: IProovException? = null
4545

46-
private fun sessionStateListener() {
47-
coroutineScope.launch {
48-
launcher.sessionsStates.collect { sessionState ->
49-
sessionState?.let {
50-
sessionState.state.let { state ->
46+
private fun observeSessionState(session: IProov.Session, whenReady: (() -> Unit)? = null) {
47+
sessionStateJob?.cancel()
48+
sessionStateJob = coroutineScope.launch(Dispatchers.IO) {
49+
kotlin.runCatching {
50+
session.state
51+
.onSubscription { whenReady?.invoke() }
52+
.collect { state ->
5153
withContext(Dispatchers.Main) {
5254
when (state) {
53-
is IProov.IProovState.Connecting -> {
55+
is IProov.State.Connecting -> {
5456
eventSink?.success(hashMapOf("event" to "connecting"))
5557
}
5658

57-
is IProov.IProovState.Connected -> {
59+
is IProov.State.Connected -> {
5860
eventSink?.success(hashMapOf("event" to "connected"))
5961
}
6062

61-
is IProov.IProovState.Processing -> {
63+
is IProov.State.Processing -> {
6264
eventSink?.success(
6365
hashMapOf(
6466
"event" to "processing",
@@ -68,7 +70,7 @@ class IProovSDKPlugin : FlutterPlugin {
6870
)
6971
}
7072

71-
is IProov.IProovState.Success -> {
73+
is IProov.State.Success -> {
7274
val frameArray = state.successResult.frame?.let { bmp ->
7375
val stream = ByteArrayOutputStream()
7476
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream)
@@ -86,7 +88,7 @@ class IProovSDKPlugin : FlutterPlugin {
8688
eventSink?.endOfStream()
8789
}
8890

89-
is IProov.IProovState.Failure -> {
91+
is IProov.State.Failure -> {
9092
val context = flutterPluginBinding!!.applicationContext
9193

9294
val frameArray = state.failureResult.frame?.let { bmp ->
@@ -108,12 +110,12 @@ class IProovSDKPlugin : FlutterPlugin {
108110
eventSink?.endOfStream()
109111
}
110112

111-
is IProov.IProovState.Error -> {
113+
is IProov.State.Error -> {
112114
eventSink?.success(state.exception.serialize())
113115
eventSink?.endOfStream()
114116
}
115117

116-
is IProov.IProovState.Canceled -> {
118+
is IProov.State.Canceled -> {
117119
eventSink?.success(
118120
hashMapOf(
119121
"event" to "canceled",
@@ -125,32 +127,33 @@ class IProovSDKPlugin : FlutterPlugin {
125127
}
126128
}
127129
}
128-
}
129130
}
130131
}
131132
}
132133

133-
private fun sessionUIStateListener() {
134-
coroutineScope.launch {
135-
launcher.sessionsUIStates.collect { sessionUIState ->
136-
sessionUIState?.let {
137-
withContext(Dispatchers.Main) {
138-
when (sessionUIState.state) {
139-
IProov.IProovUIState.NotStarted -> {
140-
uiEventSink?.success(hashMapOf("uiEvent" to "not_started"))
141-
}
134+
private fun observeSessionUIState(session: IProov.Session) {
135+
sessionUIStateJob?.cancel()
136+
sessionUIStateJob = coroutineScope.launch(Dispatchers.IO) {
137+
kotlin.runCatching {
138+
session.uiState
139+
.collect { sessionUIState ->
140+
withContext(Dispatchers.Main) {
141+
when (sessionUIState) {
142+
IProov.UIState.NotStarted -> {
143+
uiEventSink?.success(hashMapOf("uiEvent" to "not_started"))
144+
}
142145

143-
IProov.IProovUIState.Started -> {
144-
uiEventSink?.success(hashMapOf("uiEvent" to "started"))
145-
}
146+
IProov.UIState.Started -> {
147+
uiEventSink?.success(hashMapOf("uiEvent" to "started"))
148+
}
146149

147-
IProov.IProovUIState.Ended -> {
148-
uiEventSink?.success(hashMapOf("uiEvent" to "ended"))
149-
uiEventSink?.endOfStream()
150+
IProov.UIState.Ended -> {
151+
uiEventSink?.success(hashMapOf("uiEvent" to "ended"))
152+
uiEventSink?.endOfStream()
153+
}
150154
}
151155
}
152156
}
153-
}
154157
}
155158
}
156159
}
@@ -171,23 +174,23 @@ class IProovSDKPlugin : FlutterPlugin {
171174
"keyPair.sign" -> {
172175
val data = call.arguments
173176
if (data is ByteArray) {
174-
val signature = launcher.getKeyPair(context!!).sign(data)
177+
val signature = IProov.getKeyPair(context!!).sign(data)
175178
result.success(signature)
176179
} else {
177180
result.error("INVALID", "Invalid argument passed", null)
178181
}
179182
}
180183

181-
"keyPair.publicKey.getPem" -> result.success(launcher.getKeyPair(context!!).publicKey.pem)
182-
"keyPair.publicKey.getDer" -> result.success(launcher.getKeyPair(context!!).publicKey.der)
184+
"keyPair.publicKey.getPem" -> result.success(IProov.getKeyPair(context!!).publicKey.pem)
185+
"keyPair.publicKey.getDer" -> result.success(IProov.getKeyPair(context!!).publicKey.der)
183186
"cancel" -> cancelSession()
184187
else -> result.notImplemented()
185188
}
186189
}
187190

188191
private fun cancelSession() {
189192
coroutineScope.launch {
190-
launcher.currentSession()?.cancel()
193+
IProov.session?.cancel()
191194
}
192195
}
193196

@@ -227,13 +230,23 @@ class IProovSDKPlugin : FlutterPlugin {
227230
}
228231

229232
coroutineScope.launch {
230-
launcher.launch(context, streamingUrl, token, options)
233+
IProov.createSession(context, streamingUrl, token, options).let { session ->
234+
// Observe first, then start
235+
observeSession(session) {
236+
session.start()
237+
}
238+
}
231239
}
232240
}
233241
}
234242
}
235243
}
236244

245+
private fun observeSession(session: IProov.Session, whenReady: (() -> Unit)? = null) {
246+
observeSessionState(session, whenReady)
247+
observeSessionUIState(session)
248+
}
249+
237250
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
238251
this.flutterPluginBinding = flutterPluginBinding
239252

@@ -255,7 +268,7 @@ class IProovSDKPlugin : FlutterPlugin {
255268

256269
override fun onCancel(arguments: Any?) {
257270
coroutineScope.launch {
258-
launcher.currentSession()?.cancel()
271+
IProov.session?.cancel()
259272
}
260273
eventSink = null
261274
}

example/android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ android {
4040
defaultConfig {
4141
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
4242
applicationId "com.iproov.flutter.example"
43-
minSdkVersion 21
43+
minSdkVersion 26
4444
targetSdkVersion 33
4545
versionCode flutterVersionCode.toInteger()
4646
versionName flutterVersionName

example/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ subprojects {
2727
project.evaluationDependsOn(':app')
2828
}
2929

30-
task clean(type: Delete) {
30+
tasks.register("clean", Delete) {
3131
delete rootProject.buildDir
3232
}

example/ios/Podfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
platform :ios, '12.0'
1+
platform :ios, '13.0'
22
source 'https://github.com/CocoaPods/Specs.git'
33
use_frameworks!
44

example/ios/Podfile.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
PODS:
22
- Flutter (1.0.0)
3-
- iProov (11.1.1)
4-
- iproov_flutter (4.0.4):
3+
- iProov (12.0.0)
4+
- iproov_flutter (5.0.0):
55
- Flutter
6-
- iProov (= 11.1.1)
6+
- iProov (= 12.0.0)
77

88
DEPENDENCIES:
99
- Flutter (from `Flutter`)
@@ -21,9 +21,9 @@ EXTERNAL SOURCES:
2121

2222
SPEC CHECKSUMS:
2323
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
24-
iProov: 14fa45ff813bccd32274ecce2694445aba4956e4
25-
iproov_flutter: 4cdb91308e413eb8fdcfcb8f4cf282d76a13be01
24+
iProov: 1921d2fdbd8f8fa24d4694c2150c2c0bac0371a6
25+
iproov_flutter: 46b6252fff2a552174ee56ce91d92d22434ef729
2626

27-
PODFILE CHECKSUM: 3b63cf14198dad73e5eaccaa94ed2fb1260f5b72
27+
PODFILE CHECKSUM: 61e432a29a6cfb9fc7ca7cacd9dce49cb7fb3466
2828

2929
COCOAPODS: 1.15.2

example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@
365365
"$(PROJECT_DIR)/Flutter",
366366
);
367367
INFOPLIST_FILE = Runner/Info.plist;
368-
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
368+
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
369369
LD_RUNPATH_SEARCH_PATHS = (
370370
"$(inherited)",
371371
"@executable_path/Frameworks",
@@ -503,7 +503,7 @@
503503
"$(PROJECT_DIR)/Flutter",
504504
);
505505
INFOPLIST_FILE = Runner/Info.plist;
506-
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
506+
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
507507
LD_RUNPATH_SEARCH_PATHS = (
508508
"$(inherited)",
509509
"@executable_path/Frameworks",
@@ -535,7 +535,7 @@
535535
"$(PROJECT_DIR)/Flutter",
536536
);
537537
INFOPLIST_FILE = Runner/Info.plist;
538-
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
538+
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
539539
LD_RUNPATH_SEARCH_PATHS = (
540540
"$(inherited)",
541541
"@executable_path/Frameworks",

ios/iproov_flutter.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ Pod::Spec.new do |s|
1414
s.source_files = 'Classes/**/*'
1515

1616
s.dependency 'Flutter'
17-
s.dependency 'iProov', '11.1.1'
17+
s.dependency 'iProov', '12.0.0'
1818

1919
s.swift_version = '5.5'
20-
s.platform = :ios, '12.0'
20+
s.platform = :ios, '13.0'
2121
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
2222
end

0 commit comments

Comments
 (0)