@pensasystems/pensa-react-native 0.1.0-beta-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/LICENSE +20 -0
  2. package/PensaSdkReactNative.podspec +25 -0
  3. package/README.md +373 -0
  4. package/android/build.gradle +90 -0
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +3 -0
  7. package/android/src/main/AndroidManifestNew.xml +2 -0
  8. package/android/src/main/java/com/pensasdkreactnative/PensaEventEmitterModule.kt +21 -0
  9. package/android/src/main/java/com/pensasdkreactnative/PensaListeners.kt +44 -0
  10. package/android/src/main/java/com/pensasdkreactnative/PensaSdkReactNativeModule.kt +172 -0
  11. package/android/src/main/java/com/pensasdkreactnative/PensaSdkReactNativePackage.kt +20 -0
  12. package/ios/PensaEventEmitter.swift +26 -0
  13. package/ios/PensaListeners.swift +37 -0
  14. package/ios/PensaSdkReactNative-Bridging-Header.h +43 -0
  15. package/ios/PensaSdkReactNative.mm +48 -0
  16. package/ios/PensaSdkReactNative.swift +121 -0
  17. package/ios/Podfile +35 -0
  18. package/lib/module/events.js +11 -0
  19. package/lib/module/events.js.map +1 -0
  20. package/lib/module/index.js +42 -0
  21. package/lib/module/index.js.map +1 -0
  22. package/lib/module/package.json +1 -0
  23. package/lib/module/types.js +2 -0
  24. package/lib/module/types.js.map +1 -0
  25. package/lib/typescript/package.json +1 -0
  26. package/lib/typescript/src/events.d.ts +7 -0
  27. package/lib/typescript/src/events.d.ts.map +1 -0
  28. package/lib/typescript/src/index.d.ts +16 -0
  29. package/lib/typescript/src/index.d.ts.map +1 -0
  30. package/lib/typescript/src/types.d.ts +26 -0
  31. package/lib/typescript/src/types.d.ts.map +1 -0
  32. package/package.json +154 -0
  33. package/src/events.ts +16 -0
  34. package/src/index.tsx +77 -0
  35. package/src/types.ts +29 -0
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 PensaSystems
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
@@ -0,0 +1,25 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "PensaSdkReactNative"
7
+ s.version = package["version"]
8
+ s.summary = package["description"]
9
+ s.homepage = package["homepage"]
10
+ s.license = package["license"]
11
+ s.authors = package["author"]
12
+
13
+ s.platforms = { :ios => min_ios_version_supported }
14
+ s.source = { :git => "https://github.com/Pensasystems/pensa-react-native-sdk.git", :tag => "#{s.version}" }
15
+
16
+ s.source_files = "ios/**/*.{h,m,mm,swift}"
17
+
18
+ if respond_to?(:install_modules_dependencies, true)
19
+ install_modules_dependencies(s)
20
+ else
21
+ s.dependency "React-Core"
22
+ end
23
+
24
+ s.dependency "PensaSdk", "~> 1.0.4"
25
+ end
package/README.md ADDED
@@ -0,0 +1,373 @@
1
+ # pensa-sdk-react-native
2
+
3
+ The Pensa Mobile App SDK is a developer toolkit designed to simplify adding Pensa’s capabilities to your mobile applications. It provides pre-built libraries, tools, and APIs to accelerate development and integration, offering streamlined SDK integration, easy initialization, and comprehensive functionality. With the Pensa SDK, you can enhance your app’s features or seamlessly integrate with other services for a cohesive user experience.
4
+
5
+ ## SDK Integration
6
+
7
+ Integrating the Pensa SDK into your React Native project is simple. Follow the steps below to add the SDK and enable advanced shelf recognition features in your app:
8
+
9
+ ### 1- Install the SDK Package
10
+ Registry: https://www.npmjs.com/package/@pensasystems/pensa-react-native
11
+
12
+ Add the npm package to your project:
13
+
14
+ ```bash
15
+ npm install @pensasystems/pensa-react-native
16
+ ```
17
+
18
+ or
19
+
20
+ ```bash
21
+ yarn add @pensasystems/pensa-react-native
22
+ ```
23
+
24
+ ### 2- Install Native Dependencies (iOS)
25
+
26
+ After installing the npm package, navigate to the iOS folder and install the native dependencies using CocoaPods:
27
+
28
+ ```bash
29
+ cd ios
30
+ pod install
31
+ ```
32
+
33
+ This step is required for iOS to link the native components of the SDK.
34
+
35
+ ---
36
+
37
+ Once installation is complete, you can proceed with SDK initialization.
38
+
39
+ ## SDK Initialization
40
+
41
+ Initializing the Pensa SDK is straightforward. Follow the steps below to set up the SDK with your credentials and start using its features.
42
+
43
+ ### 1- Import and Call initPensa
44
+
45
+ Call `initPensa()` at the startup of your app, preferably in a root file like `index.js` before calling `AppRegistry.registerComponent`.
46
+
47
+ ```tsx
48
+ import {initPensa} from '@pensasystems/pensa-react-native';
49
+
50
+ initPensa({
51
+ clientId: 'YOUR_CLIENT_ID',
52
+ clientSecret: 'YOUR_CLIENT_SECRET',
53
+ isLoggingEnabled: true,
54
+ })
55
+ .then(() => {
56
+ console.log('[Pensa] SDK init success');
57
+ })
58
+ .catch((error) => {
59
+ console.log('[Pensa] SDK init error:', error);
60
+ });
61
+ ```
62
+
63
+ - `clientId` and `clientSecret` are required.
64
+ - `isLoggingEnabled` is optional. When true, internal SDK logs will be printed to console.
65
+
66
+ If `clientId` or `clientSecret` is missing, initialization will fail.
67
+
68
+ ### 2- Add Listeners (Optional)
69
+
70
+ To listen to SDK events such as upload progress, success, or failure, you can create a helper hook like below:
71
+
72
+ ```tsx
73
+ // hooks/usePensaListeners.ts
74
+ import {useEffect} from 'react';
75
+ import {PensaEvents} from '@pensasystems/pensa-react-native';
76
+
77
+ export const usePensaListeners = () => {
78
+ useEffect(() => {
79
+ const unsubscribeProgress = PensaEvents.addListener(
80
+ 'onScanUploadProgressUpdate',
81
+ (e) => {
82
+ console.log('[Pensa] Progress', e.progress, e.tdlinxId, e.scanAreaId);
83
+ },
84
+ );
85
+
86
+ const unsubscribeCompleted = PensaEvents.addListener(
87
+ 'onScanUploadCompleted',
88
+ (e) => {
89
+ console.log('[Pensa] Completed', e.tdlinxId, e.scanAreaId);
90
+ },
91
+ );
92
+
93
+ const unsubscribeFailed = PensaEvents.addListener(
94
+ 'onScanUploadFailed',
95
+ (e) => {
96
+ console.log('[Pensa] Failed', e.error, e.tdlinxId, e.scanAreaId);
97
+ },
98
+ );
99
+
100
+ const unsubscribeCantScan = PensaEvents.addListener(
101
+ 'onCantScanReported',
102
+ (e) => {
103
+ console.log('[Pensa] CantScan', e.reason, e.tdlinxId, e.scanAreaId);
104
+ },
105
+ );
106
+
107
+ return () => {
108
+ unsubscribeProgress();
109
+ unsubscribeCompleted();
110
+ unsubscribeFailed();
111
+ unsubscribeCantScan();
112
+ };
113
+ }, []);
114
+ };
115
+ ```
116
+
117
+ Then call the hook in your component:
118
+
119
+ ```tsx
120
+ import {usePensaListeners} from './hooks/usePensaListeners';
121
+
122
+ usePensaListeners();
123
+ ```
124
+
125
+ > ✅ You should call `usePensaListeners()` **before** `initPensa()`. Calling it after may result in missing early events emitted during SDK initialization.
126
+
127
+ This will automatically register and clean up all supported event listeners.
128
+
129
+ ---
130
+
131
+ Once initialized, you can use any of the SDK methods like `showShelfScans`, `showStoresScreen`, or `showScanArea`.
132
+
133
+ ## SDK Functionality
134
+
135
+ The Pensa library is a lightweight SDK that simplifies interactions through straightforward method calls. This SDK enables you to:
136
+
137
+ - **Locate stores**: Easily find the stores you're looking for.
138
+ - **Access stores directly**: Use global store IDs to access a specific store and initiate a scan directly.
139
+ - **View store history**: Conveniently access a list of previously visited stores.
140
+ - **Monitor scan uploads**: Track the upload status of your scans.
141
+
142
+ ### Sample Imports
143
+
144
+ Before using the SDK methods below, make sure to import the required functions:
145
+
146
+ ```tsx
147
+ import {
148
+ showShelfScans,
149
+ showProductScans,
150
+ showStoreSearchView,
151
+ showStoresScreen,
152
+ showScanArea,
153
+ showStockingScreen,
154
+ showStoreChecklist,
155
+ } from '@pensasystems/pensa-react-native';
156
+ ```
157
+
158
+ ### Searching stores
159
+
160
+ To initiate a store search using the Pensa SDK, integrate the following code snippet:
161
+
162
+ ```tsx
163
+ showStoreSearchView()
164
+ .catch((error) => {
165
+ console.log('Error displaying search store:', error);
166
+ });
167
+ ```
168
+
169
+ This will present a search interface where you can input keywords (e.g., store name, location) to find the desired store. Upon selecting a store from the search results, the SDK will automatically redirect you to that store's details, allowing you to begin a scan.
170
+
171
+ > The entered keyword must be at least 3 characters long.
172
+
173
+ ### Accessing Stores Directly with Global Store IDs
174
+
175
+ The Pensa SDK lets you directly access a store and initiate a scan using its global store ID. To do this, use the `showStoreChecklist` method:
176
+
177
+ ```tsx
178
+ showStoreChecklist('example-id')
179
+ .catch((error) => {
180
+ console.log('Error displaying store:', error);
181
+ });
182
+ ```
183
+
184
+ ### Sending Custom Parameters with Scans
185
+
186
+ In addition to using global store IDs, the Pensa SDK allows you to send custom parameters along with your scans. This can be useful for including company-specific information or metadata.
187
+
188
+ To send custom parameters, use the `sectionKey` and `guid` parameters in the `showStoreChecklist` method.
189
+
190
+ > It's important to note that both `sectionKey` and `guid` must be used together. If either parameter is missing, the SDK will only consider the `globalStoreId`.
191
+
192
+ ```tsx
193
+ showStoreChecklist('example-id', 'example-guid', 'example-section')
194
+ .catch((error) => {
195
+ console.log('Error displaying store:', error);
196
+ });
197
+ ```
198
+
199
+ ### Recently Visited Stores
200
+
201
+ The Pensa SDK maintains a cache of recently visited stores for easy access and reuse. This allows you to quickly return to a previously scanned store without searching for it again.
202
+
203
+ #### Adding Stores to the Cache
204
+
205
+ A store is automatically added to the "Recently Visited Stores" cache when you:
206
+ - Use the `showStoreChecklist()` method to access a store.
207
+ - Select a store from the search results after using `showStoreSearchView()`.
208
+
209
+ #### Accessing Recently Visited Stores
210
+
211
+ To display the "Recently Visited Stores" screen, use the following code:
212
+
213
+ ```tsx
214
+ showStoresScreen()
215
+ .catch((error) => {
216
+ console.log('Error displaying recently visited stores:', error);
217
+ });
218
+ ```
219
+
220
+ This will present a screen listing the recently visited stores. You can select a store from this screen to access its details and initiate a new scan.
221
+
222
+ ### Monitoring Scan Uploads
223
+
224
+ The Pensa SDK provides convenient methods to monitor the progress of your scan uploads. There are two separate methods depending on the type of scan:
225
+
226
+ #### Shelf Scans
227
+
228
+ To monitor shelf scan uploads, use the following method:
229
+
230
+ ```tsx
231
+ showShelfScans()
232
+ .catch((error) => {
233
+ console.log('Error displaying shelf uploads:', error);
234
+ });
235
+ ```
236
+
237
+ #### Product Scans
238
+
239
+ ```tsx
240
+ showProductScans()
241
+ .catch((error) => {
242
+ console.log('Error displaying product uploads:', error);
243
+ });
244
+ ```
245
+
246
+ Both methods present a screen that displays the status of each scan upload. You can use these screens to:
247
+
248
+ - Track upload progress: Observe the progress of ongoing uploads.
249
+ - View completed uploads: See a history of successfully uploaded scans.
250
+ - Cancel uploads: Stop the upload of any scan that is in progress.
251
+
252
+ These features give you complete control over your scan uploads and ensure you're always informed about their status.
253
+
254
+ ### Stocking Screen
255
+
256
+ The Pensa SDK allows you to access the stocking screen. This screen is used to review and manage stock actions related to the selected store.
257
+
258
+ ```tsx
259
+ showStockingScreen()
260
+ .catch((error) => {
261
+ console.log('Error displaying stocking screen:', error);
262
+ });
263
+ ```
264
+
265
+ ### Scan Area
266
+
267
+ To directly open a scan area, you must provide a `scanId` and either a `storeId` or a `globalStoreId`.:
268
+ ```tsx
269
+ showScanArea(scanId, storeId, globalStoreId)
270
+ .catch((error) => {
271
+ console.log('Error displaying scan area:', error);
272
+ });
273
+ ```
274
+
275
+ This method allows you to navigate directly to a scan area without going through the store selection flow.
276
+
277
+ # Troubleshooting (Android)
278
+
279
+ ## 1. Core Library Desugaring Required
280
+
281
+ If you see an error mentioning that `core library desugaring` must be enabled (typically referencing `AAR metadata` or `desugar_jdk_libs`), update your Android project as follows:
282
+
283
+ ### **Step 1 — Add desugaring dependency**
284
+
285
+ In your app-level `build.gradle`:
286
+
287
+ ```gradle
288
+ dependencies {
289
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
290
+ }
291
+ ```
292
+
293
+ ### **Step 2 — Enable desugaring & set Java 17**
294
+
295
+ Inside `android { compileOptions { ... } }`:
296
+
297
+ ```gradle
298
+ compileOptions {
299
+ sourceCompatibility JavaVersion.VERSION_17
300
+ targetCompatibility JavaVersion.VERSION_17
301
+ coreLibraryDesugaringEnabled true
302
+ }
303
+ ```
304
+
305
+ This configuration is required because the native Pensa Android SDK uses Java 17 language features.
306
+
307
+ ---
308
+
309
+ ## 2. Min SDK Version Requirement
310
+
311
+ If your Android build fails with a message indicating:
312
+
313
+ > *minSdkVersion cannot be smaller than 26 for library com.pensasystems:pensasdk*
314
+
315
+ Then your `minSdkVersion` must be updated.
316
+
317
+ ### **Fix**
318
+
319
+ In your app-level `build.gradle`:
320
+
321
+ ```gradle
322
+ defaultConfig {
323
+ minSdkVersion 26
324
+ }
325
+ ```
326
+
327
+ The native Pensa Android SDK requires **minSdk 26**.
328
+
329
+ ---
330
+
331
+ ## 3. Metro Bundler Cannot Connect in Debug Mode (Android Only)
332
+
333
+ If the Android app cannot connect to Metro (e.g., blank screen, “Unable to load script from assets”), update your debug network rules.
334
+
335
+ ### **Step 1 — Create `network_security_config.xml`**
336
+
337
+ Create a file:
338
+
339
+ ```
340
+ android/app/src/main/res/xml/network_security_config.xml
341
+ ```
342
+
343
+ With the following content:
344
+
345
+ ```xml
346
+ <?xml version="1.0" encoding="utf-8"?>
347
+ <network-security-config>
348
+ <domain-config cleartextTrafficPermitted="true">
349
+ <domain includeSubdomains="true">10.0.2.2</domain>
350
+ <domain includeSubdomains="true">localhost</domain>
351
+ <domain includeSubdomains="true">127.0.0.1</domain>
352
+ </domain-config>
353
+ </network-security-config>
354
+ ```
355
+
356
+ ### **Step 2 — Reference it in `AndroidManifest.xml`**
357
+
358
+ Inside your `<application>` tag:
359
+
360
+ ```xml
361
+ <application
362
+ android:networkSecurityConfig="@xml/network_security_config"
363
+ ... >
364
+ ```
365
+
366
+ This allows the Android emulator to access the React Native bundler during development.
367
+
368
+ ---
369
+
370
+ ### Example Project
371
+
372
+ For code examples and integration best practices, refer to our GitHub repository.
373
+
@@ -0,0 +1,90 @@
1
+ buildscript {
2
+ ext.getExtOrDefault = {name ->
3
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['PensaSdkReactNative_' + name]
4
+ }
5
+
6
+ repositories {
7
+ google()
8
+ mavenCentral()
9
+ maven {
10
+ url = uri("https://sdk.pensasystems.net/pensa-sdk-android")
11
+ }
12
+ }
13
+
14
+ dependencies {
15
+ classpath "com.android.tools.build:gradle:8.7.2"
16
+ // noinspection DifferentKotlinGradleVersion
17
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
18
+ }
19
+ }
20
+
21
+
22
+ apply plugin: "com.android.library"
23
+ apply plugin: "kotlin-android"
24
+
25
+
26
+ def getExtOrIntegerDefault(name) {
27
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["PensaSdkReactNative_" + name]).toInteger()
28
+ }
29
+
30
+ def supportsNamespace() {
31
+ def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
32
+ def major = parsed[0].toInteger()
33
+ def minor = parsed[1].toInteger()
34
+
35
+ // Namespace support was added in 7.3.0
36
+ return (major == 7 && minor >= 3) || major >= 8
37
+ }
38
+
39
+ android {
40
+ if (supportsNamespace()) {
41
+ namespace "com.pensasdkreactnative"
42
+
43
+ sourceSets {
44
+ main {
45
+ manifest.srcFile "src/main/AndroidManifestNew.xml"
46
+ }
47
+ }
48
+ }
49
+
50
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
51
+
52
+ defaultConfig {
53
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
54
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
55
+ }
56
+
57
+ buildTypes {
58
+ release {
59
+ minifyEnabled false
60
+ }
61
+ }
62
+
63
+ lintOptions {
64
+ disable "GradleCompatible"
65
+ }
66
+
67
+ compileOptions {
68
+ sourceCompatibility JavaVersion.VERSION_17
69
+ targetCompatibility JavaVersion.VERSION_17
70
+ coreLibraryDesugaringEnabled true
71
+ }
72
+ }
73
+
74
+ repositories {
75
+ mavenCentral()
76
+ google()
77
+ maven {
78
+ url = uri("https://sdk.pensasystems.net/pensa-sdk-android")
79
+ }
80
+ }
81
+
82
+ def kotlin_version = getExtOrDefault("kotlinVersion")
83
+
84
+ dependencies {
85
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
86
+ implementation "com.pensasystems:pensasdk:1.0.8"
87
+ implementation "com.facebook.react:react-android"
88
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
89
+ }
90
+
@@ -0,0 +1,5 @@
1
+ PensaSdkReactNative_kotlinVersion=2.0.21
2
+ PensaSdkReactNative_minSdkVersion=24
3
+ PensaSdkReactNative_targetSdkVersion=34
4
+ PensaSdkReactNative_compileSdkVersion=35
5
+ PensaSdkReactNative_ndkVersion=27.1.12297006
@@ -0,0 +1,3 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
+ package="com.pensasdkreactnative">
3
+ </manifest>
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -0,0 +1,21 @@
1
+ package com.pensasdkreactnative
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext
4
+ import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
5
+ import com.facebook.react.bridge.WritableMap
6
+ import com.facebook.react.bridge.Arguments
7
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
8
+ import com.facebook.react.bridge.ReactMethod
9
+
10
+ class PensaEventEmitterModule(private val reactContext: ReactApplicationContext) :
11
+ ReactContextBaseJavaModule(reactContext) {
12
+
13
+ override fun getName(): String = "PensaEventEmitter"
14
+
15
+ fun sendEvent(eventName: String, params: Map<String, Any?>) {
16
+ val map: WritableMap = Arguments.makeNativeMap(params)
17
+ reactContext
18
+ .getJSModule(RCTDeviceEventEmitter::class.java)
19
+ .emit(eventName, map)
20
+ }
21
+ }
@@ -0,0 +1,44 @@
1
+ package com.pensasdkreactnative
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext
4
+ import com.pensasystems.pensasdk.listener.CantScanEventListener
5
+ import com.pensasystems.pensasdk.listener.ScanUploadListener
6
+
7
+ object PensaListeners : ScanUploadListener, CantScanEventListener {
8
+
9
+ private var emitter: PensaEventEmitterModule? = null
10
+
11
+ fun setup(reactContext: ReactApplicationContext) {
12
+ emitter = PensaEventEmitterModule(reactContext)
13
+ }
14
+
15
+ override fun onScanUploadCompleted(tdlinxId: String, scanAreaId: String) {
16
+ emitter?.sendEvent("onScanUploadCompleted", mapOf(
17
+ "tdlinxId" to tdlinxId,
18
+ "scanAreaId" to scanAreaId
19
+ ))
20
+ }
21
+
22
+ override fun onScanUploadFailed(tdlinxId: String, scanAreaId: String) {
23
+ emitter?.sendEvent("onScanUploadFailed", mapOf(
24
+ "tdlinxId" to tdlinxId,
25
+ "scanAreaId" to scanAreaId
26
+ ))
27
+ }
28
+
29
+ override fun onScanUploadProgressUpdate(tdlinxId: String, scanAreaId: String, progress: Int) {
30
+ emitter?.sendEvent("onScanUploadProgressUpdate", mapOf(
31
+ "tdlinxId" to tdlinxId,
32
+ "scanAreaId" to scanAreaId,
33
+ "progress" to progress
34
+ ))
35
+ }
36
+
37
+ override fun onCantScanReported(tdlinxId: String, scanAreaId: String, cantScanReason: String) {
38
+ emitter?.sendEvent("onCantScanReported", mapOf(
39
+ "tdlinxId" to tdlinxId,
40
+ "scanAreaId" to scanAreaId,
41
+ "reason" to cantScanReason
42
+ ))
43
+ }
44
+ }