capacitor-microblink 0.3.0 → 0.3.1

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.
package/README.md CHANGED
@@ -9,12 +9,38 @@ npm install capacitor-microblink
9
9
  npx cap sync
10
10
  ```
11
11
 
12
+ ### Android Auto Init (on app startup)
13
+
14
+ If you want `initializeBlinkCard` to run automatically during Android plugin load (`onCreate` phase), set plugin config values:
15
+
16
+ ```ts
17
+ // capacitor.config.ts
18
+ plugins: {
19
+ Microblink: {
20
+ licenseKey: 'YOUR_BLINKCARD_LICENSE_KEY',
21
+ licensee: 'OPTIONAL_LICENSEE',
22
+ },
23
+ }
24
+ ```
25
+
26
+ ### iOS Camera Permission
27
+
28
+ BlinkCard scanning requires camera access on iOS.
29
+
30
+ Add this key to your app `Info.plist`:
31
+
32
+ ```xml
33
+ <key>NSCameraUsageDescription</key>
34
+ <string>We need camera access to scan your card.</string>
35
+ ```
36
+
12
37
  ## API
13
38
 
14
39
  <docgen-index>
15
40
 
16
41
  * [`scanCard(...)`](#scancard)
17
42
  * [`initializeBlinkCard(...)`](#initializeblinkcard)
43
+ * [`terminateBlinkCard()`](#terminateblinkcard)
18
44
  * [Interfaces](#interfaces)
19
45
 
20
46
  </docgen-index>
@@ -56,6 +82,19 @@ Initializes BlinkCard SDK/license before scanning.
56
82
  --------------------
57
83
 
58
84
 
85
+ ### terminateBlinkCard()
86
+
87
+ ```typescript
88
+ terminateBlinkCard() => Promise<TerminateBlinkCardResult>
89
+ ```
90
+
91
+ Terminates BlinkCard SDK and clears cached plugin initialization state.
92
+
93
+ **Returns:** <code>Promise&lt;<a href="#terminateblinkcardresult">TerminateBlinkCardResult</a>&gt;</code>
94
+
95
+ --------------------
96
+
97
+
59
98
  ### Interfaces
60
99
 
61
100
 
@@ -112,4 +151,11 @@ Initializes BlinkCard SDK/license before scanning.
112
151
  | **`licenseKey`** | <code>string</code> |
113
152
  | **`licensee`** | <code>string</code> |
114
153
 
154
+
155
+ #### TerminateBlinkCardResult
156
+
157
+ | Prop | Type |
158
+ | ---------------- | -------------------- |
159
+ | **`terminated`** | <code>boolean</code> |
160
+
115
161
  </docgen-api>
@@ -23,6 +23,8 @@ buildscript {
23
23
  apply plugin: 'com.android.library'
24
24
  apply plugin: 'org.jetbrains.kotlin.android'
25
25
 
26
+ def jvmTargetVersion = project.hasProperty('jvmTargetVersion') ? project.property('jvmTargetVersion') : '17'
27
+
26
28
  android {
27
29
  namespace = "com.otto.microblink"
28
30
  compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
@@ -45,11 +47,11 @@ android {
45
47
  disable += ["Aligned16KB"]
46
48
  }
47
49
  compileOptions {
48
- sourceCompatibility JavaVersion.VERSION_21
49
- targetCompatibility JavaVersion.VERSION_21
50
+ sourceCompatibility JavaVersion.toVersion(jvmTargetVersion)
51
+ targetCompatibility JavaVersion.toVersion(jvmTargetVersion)
50
52
  }
51
53
  kotlinOptions {
52
- jvmTarget = '21'
54
+ jvmTarget = jvmTargetVersion
53
55
  }
54
56
  }
55
57
 
@@ -8,6 +8,18 @@ import kotlinx.coroutines.Dispatchers
8
8
  import kotlinx.coroutines.launch
9
9
 
10
10
  object BlinkCardInitBridge {
11
+ private fun resetSdkInstance() {
12
+ try {
13
+ val sdkField = BlinkCardSdk::class.java.getDeclaredField("sdkInstance")
14
+ sdkField.isAccessible = true
15
+ val existingSdk = sdkField.get(null) as? BlinkCardSdk
16
+ existingSdk?.close()
17
+ sdkField.set(null, null)
18
+ } catch (_: Throwable) {
19
+ // Best-effort reset. If reflection fails, initialization may still succeed.
20
+ }
21
+ }
22
+
11
23
  @JvmStatic
12
24
  fun initialize(
13
25
  context: Context,
@@ -16,14 +28,36 @@ object BlinkCardInitBridge {
16
28
  callback: (Throwable?) -> Unit
17
29
  ) {
18
30
  CoroutineScope(Dispatchers.Main).launch {
19
- val result = BlinkCardSdk.initializeSdk(
20
- context,
31
+ resetSdkInstance()
32
+ val normalizedLicenseKey = licenseKey.trim()
33
+ val normalizedLicensee = licensee?.trim()?.takeIf { it.isNotEmpty() }
34
+ val settings = if (normalizedLicensee != null) {
35
+ BlinkCardSdkSettings(
36
+ licenseKey = normalizedLicenseKey,
37
+ licensee = normalizedLicensee
38
+ )
39
+ } else {
21
40
  BlinkCardSdkSettings(
22
- licenseKey = licenseKey,
23
- licensee = licensee ?: ""
41
+ licenseKey = normalizedLicenseKey
24
42
  )
43
+ }
44
+ val result = BlinkCardSdk.initializeSdk(
45
+ context.applicationContext,
46
+ settings
25
47
  )
26
48
  callback(result.exceptionOrNull())
27
49
  }
28
50
  }
51
+
52
+ @JvmStatic
53
+ fun terminate(callback: (Throwable?) -> Unit) {
54
+ CoroutineScope(Dispatchers.Main).launch {
55
+ try {
56
+ resetSdkInstance()
57
+ callback(null)
58
+ } catch (error: Throwable) {
59
+ callback(error)
60
+ }
61
+ }
62
+ }
29
63
  }
@@ -1,16 +1,18 @@
1
1
  package com.otto.microblink;
2
2
 
3
+ import android.Manifest;
3
4
  import android.content.Intent;
4
- import android.os.Build;
5
-
5
+ import android.util.Log;
6
6
  import androidx.activity.result.ActivityResult;
7
7
 
8
8
  import com.getcapacitor.JSObject;
9
+ import com.getcapacitor.PermissionState;
9
10
  import com.getcapacitor.Plugin;
10
11
  import com.getcapacitor.PluginCall;
11
12
  import com.getcapacitor.PluginMethod;
12
13
  import com.getcapacitor.annotation.ActivityCallback;
13
14
  import com.getcapacitor.annotation.CapacitorPlugin;
15
+ import com.getcapacitor.annotation.Permission;
14
16
  import com.microblink.blinkcard.core.BlinkCardSdkSettings;
15
17
  import com.microblink.blinkcard.core.result.CardAccountResult;
16
18
  import com.microblink.blinkcard.core.result.DateResult;
@@ -26,15 +28,63 @@ import com.microblink.blinkcard.ux.contract.ScanActivityResultStatus;
26
28
  import java.util.List;
27
29
  import java.util.function.Consumer;
28
30
 
29
- @CapacitorPlugin(name = "Microblink")
31
+ @CapacitorPlugin(
32
+ name = "Microblink",
33
+ permissions = {
34
+ @Permission(alias = "camera", strings = { Manifest.permission.CAMERA })
35
+ }
36
+ )
30
37
  public class MicroblinkPlugin extends Plugin {
38
+ private static final String TAG = "MicroblinkPlugin";
31
39
 
32
40
  private boolean isBlinkCardInitialized;
33
41
  private String blinkCardLicenseKey;
34
42
  private String blinkCardLicensee;
35
43
 
44
+ @Override
45
+ public void load() {
46
+ super.load();
47
+
48
+ String configuredLicenseKey = normalized(getConfig().getString("licenseKey"));
49
+ if (configuredLicenseKey == null) {
50
+ return;
51
+ }
52
+
53
+ String configuredLicensee = normalized(getConfig().getString("licensee"));
54
+ initializeBlinkCardLicense(configuredLicenseKey, configuredLicensee, errorMessage -> {
55
+ if (errorMessage != null) {
56
+ Log.w(TAG, "Auto initializeBlinkCard on load failed: " + errorMessage);
57
+ } else {
58
+ Log.i(TAG, "BlinkCard auto-initialized from plugin config.");
59
+ }
60
+ });
61
+ }
62
+
36
63
  @PluginMethod
37
64
  public void scanCard(PluginCall call) {
65
+ if (getPermissionState("camera") != PermissionState.GRANTED) {
66
+ requestPermissionForAlias("camera", call, "cameraPermissionCallback");
67
+ return;
68
+ }
69
+
70
+ performScanCard(call);
71
+ }
72
+
73
+ @com.getcapacitor.annotation.PermissionCallback
74
+ private void cameraPermissionCallback(PluginCall call) {
75
+ if (call == null) {
76
+ return;
77
+ }
78
+
79
+ if (getPermissionState("camera") != PermissionState.GRANTED) {
80
+ call.reject("Camera permission is required to scan cards.");
81
+ return;
82
+ }
83
+
84
+ performScanCard(call);
85
+ }
86
+
87
+ private void performScanCard(PluginCall call) {
38
88
  String providedLicenseKey = normalized(call.getString("licenseKey"));
39
89
  String providedLicensee = normalized(call.getString("licensee"));
40
90
 
@@ -54,7 +104,13 @@ public class MicroblinkPlugin extends Plugin {
54
104
  return;
55
105
  }
56
106
 
57
- startBlinkCardScan(call, blinkCardLicenseKey, blinkCardLicensee);
107
+ initializeBlinkCardLicense(blinkCardLicenseKey, blinkCardLicensee, errorMessage -> {
108
+ if (errorMessage != null) {
109
+ call.reject(errorMessage);
110
+ return;
111
+ }
112
+ startBlinkCardScan(call, blinkCardLicenseKey, blinkCardLicensee);
113
+ });
58
114
  }
59
115
 
60
116
  @PluginMethod
@@ -78,6 +134,25 @@ public class MicroblinkPlugin extends Plugin {
78
134
  });
79
135
  }
80
136
 
137
+ @PluginMethod
138
+ public void terminateBlinkCard(PluginCall call) {
139
+ BlinkCardInitBridge.terminate(error -> {
140
+ if (error != null) {
141
+ call.reject("Failed to terminate BlinkCard SDK: " + error.getMessage());
142
+ return null;
143
+ }
144
+
145
+ isBlinkCardInitialized = false;
146
+ blinkCardLicenseKey = null;
147
+ blinkCardLicensee = null;
148
+
149
+ JSObject payload = new JSObject();
150
+ payload.put("terminated", true);
151
+ call.resolve(payload);
152
+ return null;
153
+ });
154
+ }
155
+
81
156
  private void startBlinkCardScan(PluginCall call, String licenseKey, String licensee) {
82
157
  if (getContext() == null) {
83
158
  call.reject("Unable to start BlinkCard scan: Context is unavailable.");
@@ -141,6 +216,7 @@ public class MicroblinkPlugin extends Plugin {
141
216
  }
142
217
 
143
218
  if (status == ScanActivityResultStatus.ErrorSdkInit) {
219
+ isBlinkCardInitialized = false;
144
220
  call.reject("BlinkCard scan failed because SDK initialization in scan activity failed.");
145
221
  return;
146
222
  }
@@ -160,23 +236,12 @@ public class MicroblinkPlugin extends Plugin {
160
236
 
161
237
  List<CardAccountResult> cardAccounts = result.getCardAccounts();
162
238
  if (cardAccounts != null && !cardAccounts.isEmpty()) {
163
- CardAccountResult primaryAccount = null;
164
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
165
- primaryAccount = cardAccounts.getFirst();
166
- payload.put("cardNumber", primaryAccount.getCardNumber());
167
- payload.put("cardNumberValid", primaryAccount.getCardNumberValid());
168
- payload.put("cardNumberPrefix", primaryAccount.getCardNumberPrefix());
169
- payload.put("cvv", primaryAccount.getCvv());
170
- payload.put("expiryDate", toBlinkCardDate(primaryAccount.getExpiryDate()));
171
- } else {
172
- primaryAccount = cardAccounts.get(0);
173
- payload.put("cardNumber", primaryAccount.getCardNumber());
174
- payload.put("cardNumberValid", primaryAccount.getCardNumberValid());
175
- payload.put("cardNumberPrefix", primaryAccount.getCardNumberPrefix());
176
- payload.put("cvv", primaryAccount.getCvv());
177
- payload.put("expiryDate", toBlinkCardDate(primaryAccount.getExpiryDate()));
178
- }
179
-
239
+ CardAccountResult primaryAccount = cardAccounts.get(0);
240
+ payload.put("cardNumber", primaryAccount.getCardNumber());
241
+ payload.put("cardNumberValid", primaryAccount.getCardNumberValid());
242
+ payload.put("cardNumberPrefix", primaryAccount.getCardNumberPrefix());
243
+ payload.put("cvv", primaryAccount.getCvv());
244
+ payload.put("expiryDate", toBlinkCardDate(primaryAccount.getExpiryDate()));
180
245
  }
181
246
 
182
247
  call.resolve(payload);
@@ -216,9 +281,13 @@ public class MicroblinkPlugin extends Plugin {
216
281
  }
217
282
 
218
283
  private String normalized(String value) {
219
- if (value == null || value.isEmpty()) {
284
+ if (value == null) {
285
+ return null;
286
+ }
287
+ String trimmed = value.trim();
288
+ if (trimmed.isEmpty()) {
220
289
  return null;
221
290
  }
222
- return value;
291
+ return trimmed;
223
292
  }
224
293
  }
package/dist/docs.json CHANGED
@@ -42,6 +42,18 @@
42
42
  "InitializeBlinkCardOptions"
43
43
  ],
44
44
  "slug": "initializeblinkcard"
45
+ },
46
+ {
47
+ "name": "terminateBlinkCard",
48
+ "signature": "() => Promise<TerminateBlinkCardResult>",
49
+ "parameters": [],
50
+ "returns": "Promise<TerminateBlinkCardResult>",
51
+ "tags": [],
52
+ "docs": "Terminates BlinkCard SDK and clears cached plugin initialization state.",
53
+ "complexTypes": [
54
+ "TerminateBlinkCardResult"
55
+ ],
56
+ "slug": "terminateblinkcard"
45
57
  }
46
58
  ],
47
59
  "properties": []
@@ -261,6 +273,22 @@
261
273
  "type": "string | undefined"
262
274
  }
263
275
  ]
276
+ },
277
+ {
278
+ "name": "TerminateBlinkCardResult",
279
+ "slug": "terminateblinkcardresult",
280
+ "docs": "",
281
+ "tags": [],
282
+ "methods": [],
283
+ "properties": [
284
+ {
285
+ "name": "terminated",
286
+ "tags": [],
287
+ "docs": "",
288
+ "complexTypes": [],
289
+ "type": "boolean"
290
+ }
291
+ ]
264
292
  }
265
293
  ],
266
294
  "enums": [],
@@ -20,6 +20,9 @@ export interface InitializeBlinkCardOptions {
20
20
  export interface InitializeBlinkCardResult {
21
21
  initialized: boolean;
22
22
  }
23
+ export interface TerminateBlinkCardResult {
24
+ terminated: boolean;
25
+ }
23
26
  export interface ScanCardResult {
24
27
  canceled: boolean;
25
28
  resultState?: 'empty' | 'uncertain' | 'valid' | 'stageValid';
@@ -41,4 +44,8 @@ export interface MicroblinkPlugin {
41
44
  * Initializes BlinkCard SDK/license before scanning.
42
45
  */
43
46
  initializeBlinkCard(options: InitializeBlinkCardOptions): Promise<InitializeBlinkCardResult>;
47
+ /**
48
+ * Terminates BlinkCard SDK and clears cached plugin initialization state.
49
+ */
50
+ terminateBlinkCard(): Promise<TerminateBlinkCardResult>;
44
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface BlinkCardDate {\n day: number;\n month: number;\n year: number;\n}\n\nexport interface ScanCardOptions {\n licenseKey?: string;\n licensee?: string;\n extractOwner?: boolean;\n extractExpiryDate?: boolean;\n extractCvv?: boolean;\n extractIban?: boolean;\n allowInvalidCardNumber?: boolean;\n enableEditScreen?: boolean;\n}\n\nexport interface InitializeBlinkCardOptions {\n licenseKey: string;\n licensee?: string;\n}\n\nexport interface InitializeBlinkCardResult {\n initialized: boolean;\n}\n\nexport interface ScanCardResult {\n canceled: boolean;\n resultState?: 'empty' | 'uncertain' | 'valid' | 'stageValid';\n processingStatus?:\n | 'success'\n | 'detectionFailed'\n | 'imagePreprocessingFailed'\n | 'stabilityTestFailed'\n | 'scanningWrongSide'\n | 'fieldIdentificationFailed'\n | 'imageReturnFailed'\n | 'unsupportedCard';\n cardNumber?: string;\n cardNumberValid?: boolean;\n cardNumberPrefix?: string;\n owner?: string;\n cvv?: string;\n iban?: string;\n expiryDate?: BlinkCardDate | null;\n}\n\nexport interface MicroblinkPlugin {\n /**\n * Starts BlinkCard card scanning flow.\n */\n scanCard(options: ScanCardOptions): Promise<ScanCardResult>;\n\n /**\n * Initializes BlinkCard SDK/license before scanning.\n */\n initializeBlinkCard(\n options: InitializeBlinkCardOptions,\n ): Promise<InitializeBlinkCardResult>;\n}\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface BlinkCardDate {\n day: number;\n month: number;\n year: number;\n}\n\nexport interface ScanCardOptions {\n licenseKey?: string;\n licensee?: string;\n extractOwner?: boolean;\n extractExpiryDate?: boolean;\n extractCvv?: boolean;\n extractIban?: boolean;\n allowInvalidCardNumber?: boolean;\n enableEditScreen?: boolean;\n}\n\nexport interface InitializeBlinkCardOptions {\n licenseKey: string;\n licensee?: string;\n}\n\nexport interface InitializeBlinkCardResult {\n initialized: boolean;\n}\n\nexport interface TerminateBlinkCardResult {\n terminated: boolean;\n}\n\nexport interface ScanCardResult {\n canceled: boolean;\n resultState?: 'empty' | 'uncertain' | 'valid' | 'stageValid';\n processingStatus?:\n | 'success'\n | 'detectionFailed'\n | 'imagePreprocessingFailed'\n | 'stabilityTestFailed'\n | 'scanningWrongSide'\n | 'fieldIdentificationFailed'\n | 'imageReturnFailed'\n | 'unsupportedCard';\n cardNumber?: string;\n cardNumberValid?: boolean;\n cardNumberPrefix?: string;\n owner?: string;\n cvv?: string;\n iban?: string;\n expiryDate?: BlinkCardDate | null;\n}\n\nexport interface MicroblinkPlugin {\n /**\n * Starts BlinkCard card scanning flow.\n */\n scanCard(options: ScanCardOptions): Promise<ScanCardResult>;\n\n /**\n * Initializes BlinkCard SDK/license before scanning.\n */\n initializeBlinkCard(\n options: InitializeBlinkCardOptions,\n ): Promise<InitializeBlinkCardResult>;\n\n /**\n * Terminates BlinkCard SDK and clears cached plugin initialization state.\n */\n terminateBlinkCard(): Promise<TerminateBlinkCardResult>;\n}\n"]}
package/dist/esm/web.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { WebPlugin } from '@capacitor/core';
2
- import type { InitializeBlinkCardOptions, InitializeBlinkCardResult, MicroblinkPlugin, ScanCardOptions, ScanCardResult } from './definitions';
2
+ import type { InitializeBlinkCardOptions, InitializeBlinkCardResult, MicroblinkPlugin, ScanCardOptions, ScanCardResult, TerminateBlinkCardResult } from './definitions';
3
3
  export declare class MicroblinkWeb extends WebPlugin implements MicroblinkPlugin {
4
4
  scanCard(_options: ScanCardOptions): Promise<ScanCardResult>;
5
5
  initializeBlinkCard(_options: InitializeBlinkCardOptions): Promise<InitializeBlinkCardResult>;
6
+ terminateBlinkCard(): Promise<TerminateBlinkCardResult>;
6
7
  }
package/dist/esm/web.js CHANGED
@@ -6,5 +6,8 @@ export class MicroblinkWeb extends WebPlugin {
6
6
  async initializeBlinkCard(_options) {
7
7
  throw this.unimplemented('BlinkCard is only available on Android and iOS.');
8
8
  }
9
+ async terminateBlinkCard() {
10
+ throw this.unimplemented('BlinkCard is only available on Android and iOS.');
11
+ }
9
12
  }
10
13
  //# sourceMappingURL=web.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAU5C,MAAM,OAAO,aAAc,SAAQ,SAAS;IAC1C,KAAK,CAAC,QAAQ,CAAC,QAAyB;QACtC,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,mBAAmB,CACvB,QAAoC;QAEpC,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n InitializeBlinkCardOptions,\n InitializeBlinkCardResult,\n MicroblinkPlugin,\n ScanCardOptions,\n ScanCardResult,\n} from './definitions';\n\nexport class MicroblinkWeb extends WebPlugin implements MicroblinkPlugin {\n async scanCard(_options: ScanCardOptions): Promise<ScanCardResult> {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n\n async initializeBlinkCard(\n _options: InitializeBlinkCardOptions,\n ): Promise<InitializeBlinkCardResult> {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n}\n"]}
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAW5C,MAAM,OAAO,aAAc,SAAQ,SAAS;IAC1C,KAAK,CAAC,QAAQ,CAAC,QAAyB;QACtC,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,mBAAmB,CACvB,QAAoC;QAEpC,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n InitializeBlinkCardOptions,\n InitializeBlinkCardResult,\n MicroblinkPlugin,\n ScanCardOptions,\n ScanCardResult,\n TerminateBlinkCardResult,\n} from './definitions';\n\nexport class MicroblinkWeb extends WebPlugin implements MicroblinkPlugin {\n async scanCard(_options: ScanCardOptions): Promise<ScanCardResult> {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n\n async initializeBlinkCard(\n _options: InitializeBlinkCardOptions,\n ): Promise<InitializeBlinkCardResult> {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n\n async terminateBlinkCard(): Promise<TerminateBlinkCardResult> {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n}\n"]}
@@ -13,6 +13,9 @@ class MicroblinkWeb extends core.WebPlugin {
13
13
  async initializeBlinkCard(_options) {
14
14
  throw this.unimplemented('BlinkCard is only available on Android and iOS.');
15
15
  }
16
+ async terminateBlinkCard() {
17
+ throw this.unimplemented('BlinkCard is only available on Android and iOS.');
18
+ }
16
19
  }
17
20
 
18
21
  var web = /*#__PURE__*/Object.freeze({
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Microblink = registerPlugin('Microblink', {\n web: () => import('./web').then((m) => new m.MicroblinkWeb()),\n});\nexport * from './definitions';\nexport { Microblink };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class MicroblinkWeb extends WebPlugin {\n async scanCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n async initializeBlinkCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AACK,MAAC,UAAU,GAAGA,mBAAc,CAAC,YAAY,EAAE;AAChD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;AACjE,CAAC;;ACFM,MAAM,aAAa,SAASC,cAAS,CAAC;AAC7C,IAAI,MAAM,QAAQ,CAAC,QAAQ,EAAE;AAC7B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,MAAM,mBAAmB,CAAC,QAAQ,EAAE;AACxC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ;;;;;;;;;"}
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Microblink = registerPlugin('Microblink', {\n web: () => import('./web').then((m) => new m.MicroblinkWeb()),\n});\nexport * from './definitions';\nexport { Microblink };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class MicroblinkWeb extends WebPlugin {\n async scanCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n async initializeBlinkCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n async terminateBlinkCard() {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AACK,MAAC,UAAU,GAAGA,mBAAc,CAAC,YAAY,EAAE;AAChD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;AACjE,CAAC;;ACFM,MAAM,aAAa,SAASC,cAAS,CAAC;AAC7C,IAAI,MAAM,QAAQ,CAAC,QAAQ,EAAE;AAC7B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,MAAM,mBAAmB,CAAC,QAAQ,EAAE;AACxC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,MAAM,kBAAkB,GAAG;AAC/B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ;;;;;;;;;"}
package/dist/plugin.js CHANGED
@@ -12,6 +12,9 @@ var capacitorMicroblink = (function (exports, core) {
12
12
  async initializeBlinkCard(_options) {
13
13
  throw this.unimplemented('BlinkCard is only available on Android and iOS.');
14
14
  }
15
+ async terminateBlinkCard() {
16
+ throw this.unimplemented('BlinkCard is only available on Android and iOS.');
17
+ }
15
18
  }
16
19
 
17
20
  var web = /*#__PURE__*/Object.freeze({
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Microblink = registerPlugin('Microblink', {\n web: () => import('./web').then((m) => new m.MicroblinkWeb()),\n});\nexport * from './definitions';\nexport { Microblink };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class MicroblinkWeb extends WebPlugin {\n async scanCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n async initializeBlinkCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,UAAU,GAAGA,mBAAc,CAAC,YAAY,EAAE;IAChD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;IACjE,CAAC;;ICFM,MAAM,aAAa,SAASC,cAAS,CAAC;IAC7C,IAAI,MAAM,QAAQ,CAAC,QAAQ,EAAE;IAC7B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,MAAM,mBAAmB,CAAC,QAAQ,EAAE;IACxC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Microblink = registerPlugin('Microblink', {\n web: () => import('./web').then((m) => new m.MicroblinkWeb()),\n});\nexport * from './definitions';\nexport { Microblink };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class MicroblinkWeb extends WebPlugin {\n async scanCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n async initializeBlinkCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n async terminateBlinkCard() {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,UAAU,GAAGA,mBAAc,CAAC,YAAY,EAAE;IAChD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;IACjE,CAAC;;ICFM,MAAM,aAAa,SAASC,cAAS,CAAC;IAC7C,IAAI,MAAM,QAAQ,CAAC,QAAQ,EAAE;IAC7B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,MAAM,mBAAmB,CAAC,QAAQ,EAAE;IACxC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ;;;;;;;;;;;;;;;"}
@@ -2,6 +2,7 @@ import Foundation
2
2
  import Capacitor
3
3
  import Combine
4
4
  import SwiftUI
5
+ import AVFoundation
5
6
  import BlinkCard
6
7
  import BlinkCardUX
7
8
 
@@ -11,7 +12,8 @@ public class MicroblinkPlugin: CAPPlugin, CAPBridgedPlugin {
11
12
  public let jsName = "Microblink"
12
13
  public let pluginMethods: [CAPPluginMethod] = [
13
14
  CAPPluginMethod(name: "initializeBlinkCard", returnType: CAPPluginReturnPromise),
14
- CAPPluginMethod(name: "scanCard", returnType: CAPPluginReturnPromise)
15
+ CAPPluginMethod(name: "scanCard", returnType: CAPPluginReturnPromise),
16
+ CAPPluginMethod(name: "terminateBlinkCard", returnType: CAPPluginReturnPromise)
15
17
  ]
16
18
 
17
19
  private enum PluginError: LocalizedError {
@@ -58,6 +60,12 @@ public class MicroblinkPlugin: CAPPlugin, CAPBridgedPlugin {
58
60
  }
59
61
 
60
62
  @objc public func scanCard(_ call: CAPPluginCall) {
63
+ ensureCameraPermission(call) { [weak self] in
64
+ self?.performScanCard(call)
65
+ }
66
+ }
67
+
68
+ private func performScanCard(_ call: CAPPluginCall) {
61
69
  if pendingBlinkCardCallId != nil {
62
70
  call.reject("A BlinkCard flow is already running.")
63
71
  return
@@ -100,6 +108,39 @@ public class MicroblinkPlugin: CAPPlugin, CAPBridgedPlugin {
100
108
  }
101
109
  }
102
110
 
111
+ private func ensureCameraPermission(_ call: CAPPluginCall, onGranted: @escaping () -> Void) {
112
+ let status = AVCaptureDevice.authorizationStatus(for: .video)
113
+ switch status {
114
+ case .authorized:
115
+ onGranted()
116
+ case .notDetermined:
117
+ AVCaptureDevice.requestAccess(for: .video) { granted in
118
+ DispatchQueue.main.async {
119
+ if granted {
120
+ onGranted()
121
+ } else {
122
+ call.reject("Camera permission is required to scan cards.")
123
+ }
124
+ }
125
+ }
126
+ case .denied, .restricted:
127
+ call.reject("Camera permission is required to scan cards. Enable it in iOS Settings.")
128
+ @unknown default:
129
+ call.reject("Unable to determine camera permission status.")
130
+ }
131
+ }
132
+
133
+ @objc public func terminateBlinkCard(_ call: CAPPluginCall) {
134
+ Task {
135
+ await BlinkCardSdk.terminateBlinkCardSdk()
136
+ await MainActor.run {
137
+ self.blinkCardSdk = nil
138
+ self.isBlinkCardInitialized = false
139
+ call.resolve(["terminated": true])
140
+ }
141
+ }
142
+ }
143
+
103
144
  private func startBlinkCardScan(call: CAPPluginCall, sdk: BlinkCardSdk, presentingViewController: UIViewController) async throws {
104
145
  let extractionSettings = ExtractionSettings(
105
146
  extractIban: call.getBool("extractIban") ?? true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-microblink",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Capacitor plugin for microblink",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",