capacitor-record360sdk 8.25.0 → 8.30.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.
@@ -11,8 +11,8 @@ Pod::Spec.new do |s|
11
11
  s.author = package['author']
12
12
  s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
13
  s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
14
- s.ios.deployment_target = '14.0'
14
+ s.ios.deployment_target = '15.0'
15
15
  s.dependency 'Capacitor'
16
- s.dependency 'Record360SDK', '4.23.2'
16
+ s.dependency 'Record360SDK', '4.24.7'
17
17
  s.swift_version = '5.1'
18
18
  end
package/README.md CHANGED
@@ -40,12 +40,12 @@ launchRecord360(identity?: Record360Identity | undefined) => Promise<void>
40
40
  ### launchReferenceCapture(...)
41
41
 
42
42
  ```typescript
43
- launchReferenceCapture(options: { referenceNumber: string; department?: string; sequence?: string; identity?: Record360Identity; }) => Promise<void>
43
+ launchReferenceCapture(options: { referenceNumber: string; department?: string; sequence?: string; fieldData?: Record360FieldData; identity?: Record360Identity; }) => Promise<void>
44
44
  ```
45
45
 
46
- | Param | Type |
47
- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
48
- | **`options`** | <code>{ referenceNumber: string; department?: string; sequence?: string; identity?: <a href="#record360identity">Record360Identity</a>; }</code> |
46
+ | Param | Type |
47
+ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
48
+ | **`options`** | <code>{ referenceNumber: string; department?: string; sequence?: string; fieldData?: <a href="#record360fielddata">Record360FieldData</a>; identity?: <a href="#record360identity">Record360Identity</a>; }</code> |
49
49
 
50
50
  --------------------
51
51
 
@@ -53,13 +53,13 @@ launchReferenceCapture(options: { referenceNumber: string; department?: string;
53
53
  ### addListener('Record360Event', ...)
54
54
 
55
55
  ```typescript
56
- addListener(eventName: 'Record360Event', listenerFunc: (data: { type: 'onFailedToAuthenticate' | 'onInspectionCancelled' | 'onInspectionComplete' | 'onInspectionUploadFailed' | 'onInspectionUploadProgress' | 'onInspectionUploaded' | 'onInspectionStarted' | 'onUserAuthenticated'; referenceNumber?: string; bytesComplete?: number; bytesTotal?: number; error?: string; userId?: string; username?: string; inspectionJSON?: string; }) => void) => Promise<PluginListenerHandle>
56
+ addListener(eventName: 'Record360Event', listenerFunc: (data: { type: 'onFailedToAuthenticate' | 'onInspectionCancelled' | 'onInspectionComplete' | 'onInspectionUploadFailed' | 'onInspectionUploadProgress' | 'onInspectionUploaded' | 'onInspectionUploadDeleted' | 'onInspectionStarted' | 'onUserAuthenticated' | 'onSDKShouldRelaunch' | 'onSDKShouldExit'; referenceNumber?: string; inspectionNonce?: string; percentComplete?: number; error?: string; userId?: string; inspectionJSON?: string; }) => void) => Promise<PluginListenerHandle>
57
57
  ```
58
58
 
59
- | Param | Type |
60
- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
61
- | **`eventName`** | <code>'Record360Event'</code> |
62
- | **`listenerFunc`** | <code>(data: { type: 'onFailedToAuthenticate' \| 'onInspectionCancelled' \| 'onInspectionComplete' \| 'onInspectionUploadFailed' \| 'onInspectionUploadProgress' \| 'onInspectionUploaded' \| 'onInspectionStarted' \| 'onUserAuthenticated'; referenceNumber?: string; bytesComplete?: number; bytesTotal?: number; error?: string; userId?: string; username?: string; inspectionJSON?: string; }) =&gt; void</code> |
59
+ | Param | Type |
60
+ | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
61
+ | **`eventName`** | <code>'Record360Event'</code> |
62
+ | **`listenerFunc`** | <code>(data: { type: 'onFailedToAuthenticate' \| 'onInspectionCancelled' \| 'onInspectionComplete' \| 'onInspectionUploadFailed' \| 'onInspectionUploadProgress' \| 'onInspectionUploaded' \| 'onInspectionUploadDeleted' \| 'onInspectionStarted' \| 'onUserAuthenticated' \| 'onSDKShouldRelaunch' \| 'onSDKShouldExit'; referenceNumber?: string; inspectionNonce?: string; percentComplete?: number; error?: string; userId?: string; inspectionJSON?: string; }) =&gt; void</code> |
63
63
 
64
64
  **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
65
65
 
@@ -99,4 +99,37 @@ addListener(eventName: 'Record360Event', listenerFunc: (data: { type: 'onFailedT
99
99
 
100
100
  <code><a href="#r360passwordidentity">R360PasswordIdentity</a> | <a href="#r360usertokenidentity">R360UserTokenIdentity</a></code>
101
101
 
102
+
103
+ #### Record360FieldData
104
+
105
+ <code>{ [key: string]: unknown }</code>
106
+
102
107
  </docgen-api>
108
+
109
+ ## Changelog
110
+
111
+ ### 8.30.1
112
+
113
+ Capacitor 8 release carrying the unified Record360 SDK callbacks. Pairs with Android SDK 4.30.1 and iOS SDK 4.24.7.
114
+
115
+ Requirements (updates needed in the consuming app):
116
+ - Android: `minSdkVersion` 26, Kotlin Gradle plugin 2.1 or newer (the SDK is compiled with Kotlin 2.2), compileSdk 36
117
+ - iOS: deployment target 15.0
118
+
119
+ Event payload changes on `Record360Event`:
120
+ - Every inspection event now carries `inspectionNonce`, an id unique per inspection and identical across all of that inspection's events. Reference numbers repeat across inspections of the same unit; correlate on the nonce.
121
+ - `onInspectionUploadProgress` sends `percentComplete` as a fraction from 0 to 1. `bytesComplete` and `bytesTotal` are removed.
122
+ - `onInspectionUploadFailed` carries an `error` message on both platforms.
123
+ - `onUserAuthenticated` no longer includes `username`.
124
+ - `onInspectionStarted` fires once the inspection has been created, on both platforms. It previously fired from the reference-number prefill request on Android only.
125
+
126
+ New event types:
127
+ - `onInspectionUploadDeleted`: the user removed a queued upload from the Uploads screen.
128
+ - `onSDKShouldExit`: the SDK handed control back to the app. Fires exactly once per launch, after any inspection event. On iOS the plugin dismisses the SDK view controller on this event.
129
+ - `onSDKShouldRelaunch`: iOS only; the SDK dismissed after a workflow update and the plugin relaunches it with the last launch call.
130
+
131
+ Behavior changes:
132
+ - `onInspectionCancelled` fires whenever an in-progress inspection is discarded: the delete dialog, logout, session expiry, or a new launch for a different reference number or user. On iOS it no longer fires for plain dismissal, a cancelled sign-in, or declined terms; those report `onSDKShouldExit` only.
133
+ - On iOS, `onInspectionComplete` and `onInspectionCancelled` no longer dismiss the SDK view controller themselves; dismissal happens on `onSDKShouldExit`.
134
+ - Android `onInspectionUploaded` now passes the reference number; it previously passed an internal upload id.
135
+
@@ -5,10 +5,10 @@ buildscript {
5
5
  androidxJunitVersion = '1.2.1'
6
6
  androidxEspressoCoreVersion = '3.6.1'
7
7
  androidXCore = '1.15.0'
8
- compileSdk = 35
9
- minSdkVersion = 24
10
- targetSdkVersion = 35
11
- kotlinVersion = '2.0.21'
8
+ compileSdk = 36
9
+ minSdkVersion = 26
10
+ targetSdkVersion = 36
11
+ kotlinVersion = '2.2.0'
12
12
  androidxCoreVersion = '1.15.0'
13
13
  androidxActivityVersion = '1.9.2'
14
14
  androidxFragmentVersion = '1.8.4'
@@ -101,6 +101,6 @@ dependencies {
101
101
  testImplementation "junit:junit:$junitVersion"
102
102
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
103
103
  androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
104
- implementation 'com.record360.sdk:android-sdk:4.25.3'
104
+ implementation 'com.record360.sdk:android-sdk:4.30.1'
105
105
  coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
106
106
  }
@@ -9,6 +9,7 @@ import com.getcapacitor.PluginCall
9
9
  import com.getcapacitor.PluginMethod
10
10
  import com.getcapacitor.annotation.CapacitorPlugin
11
11
  import com.record360.plugins.SampleRecord360Activity.Companion.DEPARTMENT_INTENT
12
+ import com.record360.plugins.SampleRecord360Activity.Companion.FIELD_DATA_INTENT
12
13
  import com.record360.plugins.SampleRecord360Activity.Companion.REFERENCE_NUMBER_INTENT
13
14
  import com.record360.plugins.SampleRecord360Activity.Companion.SEQUENCE_INTENT
14
15
  import com.record360.plugins.SampleRecord360Activity.Companion.USER_ID_INTENT
@@ -67,8 +68,10 @@ open class CapacitorRecord360SDKPlugin : Plugin(), IRecord360Interface {
67
68
  data?.let { dataObj ->
68
69
  val department = dataObj.getString("department")
69
70
  val sequence = dataObj.getString("sequence")
71
+ val fieldData = dataObj.getJSObject("fieldData")
70
72
  department?.let { putExtra(DEPARTMENT_INTENT, it) }
71
73
  sequence?.let { putExtra(SEQUENCE_INTENT, it) }
74
+ fieldData?.let { putExtra(FIELD_DATA_INTENT, it.toString()) }
72
75
  }
73
76
  }
74
77
 
@@ -111,82 +114,111 @@ open class CapacitorRecord360SDKPlugin : Plugin(), IRecord360Interface {
111
114
  return contractFieldData
112
115
  }
113
116
 
114
- override fun onFailedToAuthenticate(credentialsAreValid: Boolean, error: String?) {
115
- Log.i(TAG, "onFailedToAuthenticate")
117
+ override fun onFailedAuthentication(error: Throwable) {
118
+ Log.i(TAG, "onFailedAuthentication")
116
119
  val data = JSObject().apply {
117
120
  put("type", "onFailedToAuthenticate")
121
+ put("error", error.localizedMessage)
118
122
  }
119
123
  notifyListeners(EVENT_NAME, data)
120
124
  }
121
125
 
122
- override fun onInspectionCancelled(referenceNumber: String?) {
123
- Log.i(TAG, "onInspectionCancelled")
126
+ override fun onInspectionCancelled(refNum: String, inspectionNonce: String) {
127
+ Log.i(TAG, "onInspectionCancelled refNum=$refNum nonce=$inspectionNonce")
124
128
  val data = JSObject().apply {
125
129
  put("type", "onInspectionCancelled")
126
- put("referenceNumber", referenceNumber)
130
+ put("referenceNumber", refNum)
131
+ put("inspectionNonce", inspectionNonce)
127
132
  }
128
133
  notifyListeners(EVENT_NAME, data)
129
134
  }
130
135
 
131
- override fun onInspectionComplete(referenceNumber: String?) {
132
- Log.i(TAG, "onInspectionComplete")
136
+ override fun onInspectionComplete(refNum: String, inspectionNonce: String) {
137
+ Log.i(TAG, "onInspectionComplete refNum=$refNum nonce=$inspectionNonce")
133
138
  val data = JSObject().apply {
134
139
  put("type", "onInspectionComplete")
135
- put("referenceNumber", referenceNumber)
140
+ put("referenceNumber", refNum)
141
+ put("inspectionNonce", inspectionNonce)
136
142
  }
137
143
  notifyListeners(EVENT_NAME, data)
138
144
  }
139
145
 
140
- override fun onInspectionUploadFailed(referenceNumber: String?, error: String?) {
141
- Log.i(TAG, "onInspectionUploadFailed")
146
+ override fun onInspectionUploadFailed(refNum: String, inspectionNonce: String, error: String) {
147
+ Log.i(TAG, "onInspectionUploadFailed refNum=$refNum nonce=$inspectionNonce error=$error")
142
148
  val data = JSObject().apply {
143
149
  put("type", "onInspectionUploadFailed")
144
- put("referenceNumber", referenceNumber)
150
+ put("referenceNumber", refNum)
151
+ put("inspectionNonce", inspectionNonce)
145
152
  put("error", error)
146
153
  }
147
154
  notifyListeners(EVENT_NAME, data)
148
155
  }
149
156
 
150
- override fun onInspectionUploadProgress(referenceNumber: String?, complete: Long, total: Long) {
151
- Log.i(TAG, "onInspectionUploadProgress")
157
+ override fun onInspectionUploadProgress(refNum: String, inspectionNonce: String, percentComplete: Double) {
158
+ Log.i(TAG, "onInspectionUploadProgress refNum=$refNum nonce=$inspectionNonce percent=$percentComplete")
152
159
  val data = JSObject().apply {
153
160
  put("type", "onInspectionUploadProgress")
154
- put("referenceNumber", referenceNumber)
155
- put("bytesComplete", complete)
156
- put("bytesTotal", total)
161
+ put("referenceNumber", refNum)
162
+ put("inspectionNonce", inspectionNonce)
163
+ put("percentComplete", percentComplete)
157
164
  }
158
165
  notifyListeners(EVENT_NAME, data)
159
166
  }
160
167
 
161
- override fun onInspectionUploaded(referenceNumber: String?, inspectionJson: String?) {
162
- Log.i(TAG, "onInspectionUploaded")
168
+ override fun onInspectionUploaded(refNum: String, inspectionNonce: String, inspectionJSON: String) {
169
+ Log.i(TAG, "onInspectionUploaded refNum=$refNum nonce=$inspectionNonce")
163
170
  val data = JSObject().apply {
164
171
  put("type", "onInspectionUploaded")
165
- put("referenceNumber", referenceNumber)
166
- put("inspectionJSON", inspectionJson)
172
+ put("referenceNumber", refNum)
173
+ put("inspectionNonce", inspectionNonce)
174
+ put("inspectionJSON", inspectionJSON)
167
175
  }
168
176
  notifyListeners(EVENT_NAME, data)
169
177
  }
170
178
 
179
+ override fun onInspectionUploadDeleted(refNum: String, inspectionNonce: String) {
180
+ Log.i(TAG, "onInspectionUploadDeleted refNum=$refNum nonce=$inspectionNonce")
181
+ val data = JSObject().apply {
182
+ put("type", "onInspectionUploadDeleted")
183
+ put("referenceNumber", refNum)
184
+ put("inspectionNonce", inspectionNonce)
185
+ }
186
+ notifyListeners(EVENT_NAME, data)
187
+ }
188
+
189
+ override fun onSDKShouldRelaunch() {
190
+ Log.i(TAG, "onSDKShouldRelaunch")
191
+ notifyListeners(EVENT_NAME, JSObject().apply { put("type", "onSDKShouldRelaunch") })
192
+ }
193
+
194
+ override fun onSDKShouldExit() {
195
+ Log.i(TAG, "onSDKShouldExit")
196
+ notifyListeners(EVENT_NAME, JSObject().apply { put("type", "onSDKShouldExit") })
197
+ }
198
+
171
199
  override fun onReferenceNumberEnteredWithFieldData(
172
200
  referenceNumber: String?,
173
201
  fieldData: Map<String?, String?>?
174
202
  ): Map<String?, String?>? {
175
203
  Log.i(TAG, "onRefNumEntered")
204
+ return fieldData
205
+ }
206
+
207
+ override fun onInspectionStarted(refNum: String, inspectionNonce: String) {
208
+ Log.i(TAG, "onInspectionStarted refNum=$refNum nonce=$inspectionNonce")
176
209
  val data = JSObject().apply {
177
210
  put("type", "onInspectionStarted")
178
- put("referenceNumber", referenceNumber)
211
+ put("referenceNumber", refNum)
212
+ put("inspectionNonce", inspectionNonce)
179
213
  }
180
214
  notifyListeners(EVENT_NAME, data)
181
- return fieldData
182
215
  }
183
216
 
184
- override fun onUserAuthenticated(username: String?, userId: String?, token: String?) {
185
- Log.i(TAG, "onUserAuthenticated")
217
+ override fun onSuccessfulAuthentication(userToken: String, userId: String) {
218
+ Log.i(TAG, "onSuccessfulAuthentication")
186
219
  val data = JSObject().apply {
187
220
  put("type", "onUserAuthenticated")
188
221
  put("userId", userId)
189
- put("username", username)
190
222
  }
191
223
  notifyListeners(EVENT_NAME, data)
192
224
  }
@@ -4,6 +4,7 @@ import android.os.Bundle
4
4
  import com.record360.sdk.R360Identity
5
5
  import com.record360.sdk.Record360Activity
6
6
  import com.record360.sdk.ui.insets.EdgeToEdgeInitializer
7
+ import org.json.JSONObject
7
8
 
8
9
  class SampleRecord360Activity: Record360Activity() {
9
10
  override fun onCreate(savedInstanceState: Bundle?) {
@@ -15,6 +16,9 @@ class SampleRecord360Activity: Record360Activity() {
15
16
  val password = if (intent.hasExtra(USER_PASSWORD_INTENT)) intent.getStringExtra(USER_PASSWORD_INTENT) else null
16
17
  val department = if (intent.hasExtra(DEPARTMENT_INTENT)) intent.getStringExtra(DEPARTMENT_INTENT) else null
17
18
  val sequence = if (intent.hasExtra(SEQUENCE_INTENT)) intent.getStringExtra(SEQUENCE_INTENT) else null
19
+ val fieldData = if (intent.hasExtra(FIELD_DATA_INTENT)) {
20
+ parseFieldData(intent.getStringExtra(FIELD_DATA_INTENT))
21
+ } else null
18
22
  val referenceNumber = if (intent.hasExtra(REFERENCE_NUMBER_INTENT)) {
19
23
  intent.getStringExtra(REFERENCE_NUMBER_INTENT)
20
24
  } else null
@@ -22,13 +26,23 @@ class SampleRecord360Activity: Record360Activity() {
22
26
  when {
23
27
  userId != null && userToken != null -> {
24
28
  val identity = R360Identity.UserTokenIdentity(userId, userToken)
25
- startRecord360WithIdentity(this, identity, referenceNumber, department, sequence)
29
+ startRecord360WithIdentity(this, identity, referenceNumber, department, sequence, fieldData)
26
30
  }
27
31
  userName != null && password != null -> {
28
32
  val identity = R360Identity.PasswordIdentity(userName, password)
29
- startRecord360WithIdentity(this, identity, referenceNumber, department, sequence)
33
+ startRecord360WithIdentity(this, identity, referenceNumber, department, sequence, fieldData)
30
34
  }
31
- else -> startRecord360(this, referenceNumber, department, sequence, null)
35
+ else -> startRecord360(this, referenceNumber, department, sequence, null, fieldData)
36
+ }
37
+ }
38
+
39
+ private fun parseFieldData(json: String?): Map<String, String>? {
40
+ if (json.isNullOrEmpty()) return null
41
+ return try {
42
+ val obj = JSONObject(json)
43
+ obj.keys().asSequence().associateWith { key -> obj.get(key).toString() }
44
+ } catch (e: Exception) {
45
+ null
32
46
  }
33
47
  }
34
48
 
@@ -36,6 +50,7 @@ class SampleRecord360Activity: Record360Activity() {
36
50
  var REFERENCE_NUMBER_INTENT = "SampleRecord360Activity.REF_NUM_INTENT"
37
51
  var DEPARTMENT_INTENT = "SampleRecord360Activity.DEPARTMENT_INTENT"
38
52
  var SEQUENCE_INTENT = "SampleRecord360Activity.SEQUENCE_INTENT"
53
+ var FIELD_DATA_INTENT = "SampleRecord360Activity.FIELD_DATA_INTENT"
39
54
  var USER_ID_INTENT = "SampleRecord360Activity.USER_ID"
40
55
  var USER_TOKEN_INTENT = "SampleRecord360Activity.USER_TOKEN"
41
56
  var USER_NAME_INTENT = "SampleRecord360Activity.USER_NAME"
package/dist/docs.json CHANGED
@@ -25,25 +25,26 @@
25
25
  },
26
26
  {
27
27
  "name": "launchReferenceCapture",
28
- "signature": "(options: { referenceNumber: string; department?: string; sequence?: string; identity?: Record360Identity; }) => Promise<void>",
28
+ "signature": "(options: { referenceNumber: string; department?: string; sequence?: string; fieldData?: Record360FieldData; identity?: Record360Identity; }) => Promise<void>",
29
29
  "parameters": [
30
30
  {
31
31
  "name": "options",
32
32
  "docs": "",
33
- "type": "{ referenceNumber: string; department?: string | undefined; sequence?: string | undefined; identity?: Record360Identity | undefined; }"
33
+ "type": "{ referenceNumber: string; department?: string | undefined; sequence?: string | undefined; fieldData?: Record360FieldData | undefined; identity?: Record360Identity | undefined; }"
34
34
  }
35
35
  ],
36
36
  "returns": "Promise<void>",
37
37
  "tags": [],
38
38
  "docs": "",
39
39
  "complexTypes": [
40
+ "Record360FieldData",
40
41
  "Record360Identity"
41
42
  ],
42
43
  "slug": "launchreferencecapture"
43
44
  },
44
45
  {
45
46
  "name": "addListener",
46
- "signature": "(eventName: 'Record360Event', listenerFunc: (data: { type: 'onFailedToAuthenticate' | 'onInspectionCancelled' | 'onInspectionComplete' | 'onInspectionUploadFailed' | 'onInspectionUploadProgress' | 'onInspectionUploaded' | 'onInspectionStarted' | 'onUserAuthenticated'; referenceNumber?: string; bytesComplete?: number; bytesTotal?: number; error?: string; userId?: string; username?: string; inspectionJSON?: string; }) => void) => Promise<PluginListenerHandle>",
47
+ "signature": "(eventName: 'Record360Event', listenerFunc: (data: { type: 'onFailedToAuthenticate' | 'onInspectionCancelled' | 'onInspectionComplete' | 'onInspectionUploadFailed' | 'onInspectionUploadProgress' | 'onInspectionUploaded' | 'onInspectionUploadDeleted' | 'onInspectionStarted' | 'onUserAuthenticated' | 'onSDKShouldRelaunch' | 'onSDKShouldExit'; referenceNumber?: string; inspectionNonce?: string; percentComplete?: number; error?: string; userId?: string; inspectionJSON?: string; }) => void) => Promise<PluginListenerHandle>",
47
48
  "parameters": [
48
49
  {
49
50
  "name": "eventName",
@@ -53,7 +54,7 @@
53
54
  {
54
55
  "name": "listenerFunc",
55
56
  "docs": "",
56
- "type": "(data: { type: 'onFailedToAuthenticate' | 'onInspectionCancelled' | 'onInspectionComplete' | 'onInspectionUploadFailed' | 'onInspectionUploadProgress' | 'onInspectionUploaded' | 'onInspectionStarted' | 'onUserAuthenticated'; referenceNumber?: string | undefined; bytesComplete?: number | undefined; bytesTotal?: number | undefined; error?: string | undefined; userId?: string | undefined; username?: string | undefined; inspectionJSON?: string | undefined; }) => void"
57
+ "type": "(data: { type: 'onFailedToAuthenticate' | 'onInspectionCancelled' | 'onInspectionComplete' | 'onInspectionUploadFailed' | 'onInspectionUploadProgress' | 'onInspectionUploaded' | 'onInspectionUploadDeleted' | 'onInspectionStarted' | 'onUserAuthenticated' | 'onSDKShouldRelaunch' | 'onSDKShouldExit'; referenceNumber?: string | undefined; inspectionNonce?: string | undefined; percentComplete?: number | undefined; error?: string | undefined; userId?: string | undefined; inspectionJSON?: string | undefined; }) => void"
57
58
  }
58
59
  ],
59
60
  "returns": "Promise<PluginListenerHandle>",
@@ -151,6 +152,17 @@
151
152
  ]
152
153
  }
153
154
  ]
155
+ },
156
+ {
157
+ "name": "Record360FieldData",
158
+ "slug": "record360fielddata",
159
+ "docs": "",
160
+ "types": [
161
+ {
162
+ "text": "{ [key: string]: unknown }",
163
+ "complexTypes": []
164
+ }
165
+ ]
154
166
  }
155
167
  ],
156
168
  "pluginConfigs": []
@@ -8,22 +8,27 @@ export interface R360UserTokenIdentity {
8
8
  userId: string;
9
9
  userToken: string;
10
10
  }
11
+ export declare type Record360FieldData = {
12
+ [key: string]: unknown;
13
+ };
11
14
  export interface CapacitorRecord360SDKPlugin {
12
15
  launchRecord360(identity?: Record360Identity): Promise<void>;
13
16
  launchReferenceCapture(options: {
14
17
  referenceNumber: string;
15
18
  department?: string;
16
19
  sequence?: string;
20
+ fieldData?: Record360FieldData;
17
21
  identity?: Record360Identity;
18
22
  }): Promise<void>;
19
23
  addListener(eventName: 'Record360Event', listenerFunc: (data: {
20
- type: 'onFailedToAuthenticate' | 'onInspectionCancelled' | 'onInspectionComplete' | 'onInspectionUploadFailed' | 'onInspectionUploadProgress' | 'onInspectionUploaded' | 'onInspectionStarted' | 'onUserAuthenticated';
24
+ type: 'onFailedToAuthenticate' | 'onInspectionCancelled' | 'onInspectionComplete' | 'onInspectionUploadFailed' | 'onInspectionUploadProgress' | 'onInspectionUploaded' | 'onInspectionUploadDeleted' | 'onInspectionStarted' | 'onUserAuthenticated' | 'onSDKShouldRelaunch' | 'onSDKShouldExit';
21
25
  referenceNumber?: string;
22
- bytesComplete?: number;
23
- bytesTotal?: number;
26
+ /** Unique per inspection; correlates every event for the same inspection. */
27
+ inspectionNonce?: string;
28
+ /** Fraction uploaded, 0 to 1. */
29
+ percentComplete?: number;
24
30
  error?: string;
25
31
  userId?: string;
26
- username?: string;
27
32
  inspectionJSON?: string;
28
33
  }) => void): Promise<PluginListenerHandle>;
29
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from \"@capacitor/core\"\nexport type Record360Identity = R360PasswordIdentity | R360UserTokenIdentity\n\nexport interface R360PasswordIdentity {\n username: string,\n password: string\n}\n\nexport interface R360UserTokenIdentity {\n userId: string,\n userToken: string\n}\n\nexport interface CapacitorRecord360SDKPlugin {\n launchRecord360(identity?: Record360Identity): Promise<void>\n\n launchReferenceCapture(options: {\n referenceNumber: string,\n department?: string,\n sequence?: string,\n identity?: Record360Identity\n }): Promise<void>\n\n addListener(\n eventName: 'Record360Event',\n listenerFunc: (\n data: { \n type: 'onFailedToAuthenticate' | 'onInspectionCancelled' | 'onInspectionComplete' | 'onInspectionUploadFailed' | 'onInspectionUploadProgress' | 'onInspectionUploaded' | 'onInspectionStarted' | 'onUserAuthenticated',\n referenceNumber?: string,\n bytesComplete?: number,\n bytesTotal?: number,\n error?: string,\n userId?: string,\n username?: string,\n inspectionJSON?: string\n }\n ) => void,\n ): Promise<PluginListenerHandle>;\n}\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from \"@capacitor/core\"\nexport type Record360Identity = R360PasswordIdentity | R360UserTokenIdentity\n\nexport interface R360PasswordIdentity {\n username: string,\n password: string\n}\n\nexport interface R360UserTokenIdentity {\n userId: string,\n userToken: string\n}\n\nexport type Record360FieldData = { [key: string]: unknown }\n\nexport interface CapacitorRecord360SDKPlugin {\n launchRecord360(identity?: Record360Identity): Promise<void>\n\n launchReferenceCapture(options: {\n referenceNumber: string,\n department?: string,\n sequence?: string,\n fieldData?: Record360FieldData,\n identity?: Record360Identity\n }): Promise<void>\n\n addListener(\n eventName: 'Record360Event',\n listenerFunc: (\n data: {\n type: 'onFailedToAuthenticate' | 'onInspectionCancelled' | 'onInspectionComplete' | 'onInspectionUploadFailed' | 'onInspectionUploadProgress' | 'onInspectionUploaded' | 'onInspectionUploadDeleted' | 'onInspectionStarted' | 'onUserAuthenticated' | 'onSDKShouldRelaunch' | 'onSDKShouldExit',\n referenceNumber?: string,\n /** Unique per inspection; correlates every event for the same inspection. */\n inspectionNonce?: string,\n /** Fraction uploaded, 0 to 1. */\n percentComplete?: number,\n error?: string,\n userId?: string,\n inspectionJSON?: string\n }\n ) => void,\n ): Promise<PluginListenerHandle>;\n}\n"]}
package/dist/esm/web.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import { ListenerCallback, PluginListenerHandle, WebPlugin } from '@capacitor/core';
2
- import type { CapacitorRecord360SDKPlugin, Record360Identity } from './definitions';
2
+ import type { CapacitorRecord360SDKPlugin, Record360FieldData, Record360Identity } from './definitions';
3
3
  export declare class CapacitorRecord360SDKWeb extends WebPlugin implements CapacitorRecord360SDKPlugin {
4
4
  launchRecord360(_?: Record360Identity): Promise<void>;
5
5
  launchReferenceCapture(_: {
6
6
  referenceNumber: string;
7
7
  department?: string;
8
8
  sequence?: string;
9
+ fieldData?: Record360FieldData;
9
10
  identity?: Record360Identity;
10
11
  }): Promise<void>;
11
12
  addListener(_eventName: string, _listenerFunc: ListenerCallback): Promise<PluginListenerHandle>;
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIpF,MAAM,OAAO,wBAAyB,SAAQ,SAAS;IACrD,eAAe,CAAC,CAAqB;QACnC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IAED,sBAAsB,CAAC,CAAqG;QACxH,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC5C,CAAC;IAED,WAAW,CAAC,UAAkB,EAAE,aAA+B;QAC3D,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC5C,CAAC;CACF","sourcesContent":["import { ListenerCallback, PluginListenerHandle, WebPlugin } from '@capacitor/core';\n\nimport type { CapacitorRecord360SDKPlugin, Record360Identity } from './definitions';\n\nexport class CapacitorRecord360SDKWeb extends WebPlugin implements CapacitorRecord360SDKPlugin {\n launchRecord360(_?: Record360Identity): Promise<void> {\n throw new Error(\"Not available on web.\");\n }\n\n launchReferenceCapture(_: { referenceNumber: string; department?: string; sequence?: string; identity?: Record360Identity; }): Promise<void> {\n throw new Error(\"Not available on web\");\n }\n \n addListener(_eventName: string, _listenerFunc: ListenerCallback): Promise<PluginListenerHandle> {\n throw new Error(\"Not available on web\");\n }\n}"]}
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIpF,MAAM,OAAO,wBAAyB,SAAQ,SAAS;IACrD,eAAe,CAAC,CAAqB;QACnC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IAED,sBAAsB,CAAC,CAAqI;QACxJ,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC5C,CAAC;IAED,WAAW,CAAC,UAAkB,EAAE,aAA+B;QAC3D,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC5C,CAAC;CACF","sourcesContent":["import { ListenerCallback, PluginListenerHandle, WebPlugin } from '@capacitor/core';\n\nimport type { CapacitorRecord360SDKPlugin, Record360FieldData, Record360Identity } from './definitions';\n\nexport class CapacitorRecord360SDKWeb extends WebPlugin implements CapacitorRecord360SDKPlugin {\n launchRecord360(_?: Record360Identity): Promise<void> {\n throw new Error(\"Not available on web.\");\n }\n\n launchReferenceCapture(_: { referenceNumber: string; department?: string; sequence?: string; fieldData?: Record360FieldData; identity?: Record360Identity; }): Promise<void> {\n throw new Error(\"Not available on web\");\n }\n \n addListener(_eventName: string, _listenerFunc: ListenerCallback): Promise<PluginListenerHandle> {\n throw new Error(\"Not available on web\");\n }\n}"]}
@@ -14,10 +14,11 @@ public class CapacitorRecord360SDKPlugin: CAPPlugin, CAPBridgedPlugin, Record360
14
14
  public var record360: Record360?
15
15
  public var record360ViewController: Record360ViewController?
16
16
  public var hostingSDKViewController = false
17
+ private var lastLaunch: (() -> Void)?
17
18
 
18
19
  public override init() {
19
20
  super.init()
20
- self.record360 = Record360(delegate: self, allowUserToExitRecord360: true);
21
+ self.record360 = Record360(delegate: self, allowUserToExitRecord360: true, error: nil);
21
22
  }
22
23
 
23
24
  private func applySettings() {
@@ -53,7 +54,7 @@ public class CapacitorRecord360SDKPlugin: CAPPlugin, CAPBridgedPlugin, Record360
53
54
  let identity = Record360Identity(userID: userId!, userToken: userToken!)
54
55
  loadR360SDK(identity: identity, presentingVC: presentingVC)
55
56
  } else {
56
- loadR360SDKLogin(referenceNumber: nil, department: nil, sequence: nil, presentingVC: presentingVC)
57
+ loadR360SDKLogin(referenceNumber: nil, department: nil, sequence: nil, fieldData: nil, presentingVC: presentingVC)
57
58
  }
58
59
  }
59
60
 
@@ -71,6 +72,7 @@ public class CapacitorRecord360SDKPlugin: CAPPlugin, CAPBridgedPlugin, Record360
71
72
 
72
73
  let department = call.getString("department")
73
74
  let sequence = call.getString("sequence")
75
+ let fieldData = call.getObject("fieldData")
74
76
  let identityObj = call.getObject("identity")
75
77
  let username = identityObj?["username"] as? String
76
78
  let password = identityObj?["password"] as? String
@@ -79,21 +81,22 @@ public class CapacitorRecord360SDKPlugin: CAPPlugin, CAPBridgedPlugin, Record360
79
81
 
80
82
  if (username != nil && password != nil) {
81
83
  let identity = Record360Identity(userName: username!, password: password!)
82
- loadR360SDKForInspection(identity: identity, referenceNumber: referenceNumber!, department: department, sequence: sequence, presentingVC: presentingVC)
84
+ loadR360SDKForInspection(identity: identity, referenceNumber: referenceNumber!, department: department, sequence: sequence, fieldData: fieldData, presentingVC: presentingVC)
83
85
  } else if (userId != nil && userToken != nil) {
84
86
  let identity = Record360Identity(userID: userId!, userToken: userToken!)
85
- loadR360SDKForInspection(identity: identity, referenceNumber: referenceNumber!, department: department, sequence: sequence, presentingVC: presentingVC)
87
+ loadR360SDKForInspection(identity: identity, referenceNumber: referenceNumber!, department: department, sequence: sequence, fieldData: fieldData, presentingVC: presentingVC)
86
88
  } else {
87
- loadR360SDKLogin(referenceNumber: referenceNumber, department: department, sequence: sequence, presentingVC: presentingVC)
89
+ loadR360SDKLogin(referenceNumber: referenceNumber, department: department, sequence: sequence, fieldData: fieldData, presentingVC: presentingVC)
88
90
  }
89
91
  }
90
92
 
91
- private func loadR360SDKLogin(referenceNumber: String?, department: String?, sequence: String?, presentingVC: UIViewController) {
93
+ private func loadR360SDKLogin(referenceNumber: String?, department: String?, sequence: String?, fieldData: JSObject?, presentingVC: UIViewController) {
94
+ lastLaunch = { self.loadR360SDKLogin(referenceNumber: referenceNumber, department: department, sequence: sequence, fieldData: fieldData, presentingVC: presentingVC) }
92
95
  DispatchQueue.main.async {
93
96
  self.hostSDKViewController {
94
97
  let identity = Record360Identity(userName: "", password: nil)
95
98
  if (referenceNumber != nil) {
96
- self.record360?.launchReferenceCapture(referenceNumber, departmentReference: department, sequenceReference: sequence, identity: identity)
99
+ self.record360?.launchReferenceCapture(referenceNumber, departmentReference: department, sequenceReference: sequence, fieldData: fieldData, identity: identity)
97
100
  } else {
98
101
  self.record360?.launch(identity)
99
102
  }
@@ -103,6 +106,7 @@ public class CapacitorRecord360SDKPlugin: CAPPlugin, CAPBridgedPlugin, Record360
103
106
  }
104
107
 
105
108
  private func loadR360SDK(identity: Record360Identity, presentingVC: UIViewController) {
109
+ lastLaunch = { self.loadR360SDK(identity: identity, presentingVC: presentingVC) }
106
110
  DispatchQueue.main.async {
107
111
  self.hostSDKViewController {
108
112
  self.record360?.launch(identity)
@@ -111,10 +115,11 @@ public class CapacitorRecord360SDKPlugin: CAPPlugin, CAPBridgedPlugin, Record360
111
115
  }
112
116
  }
113
117
 
114
- private func loadR360SDKForInspection(identity: Record360Identity, referenceNumber: String, department: String?, sequence: String?, presentingVC: UIViewController) {
118
+ private func loadR360SDKForInspection(identity: Record360Identity, referenceNumber: String, department: String?, sequence: String?, fieldData: JSObject?, presentingVC: UIViewController) {
119
+ lastLaunch = { self.loadR360SDKForInspection(identity: identity, referenceNumber: referenceNumber, department: department, sequence: sequence, fieldData: fieldData, presentingVC: presentingVC) }
115
120
  DispatchQueue.main.async {
116
121
  self.hostSDKViewController {
117
- self.record360?.launchReferenceCapture(referenceNumber, departmentReference: department, sequenceReference: sequence, identity: identity)
122
+ self.record360?.launchReferenceCapture(referenceNumber, departmentReference: department, sequenceReference: sequence, fieldData: fieldData, identity: identity)
118
123
  self.applySettings()
119
124
  }
120
125
  }
@@ -125,54 +130,83 @@ public class CapacitorRecord360SDKPlugin: CAPPlugin, CAPBridgedPlugin, Record360
125
130
  data["type"] = "onUserAuthenticated"
126
131
  data["userId"] = userId
127
132
 
128
- notifyListeners("Record360Event", data: data)
133
+ emit(data)
129
134
  }
130
135
 
131
136
  public func onFailedAuthentication(_ error: any Error) {
132
137
  var data = JSObject()
133
138
  data["type"] = "onFailedToAuthenticate"
134
- notifyListeners("Record360Event", data: data)
139
+ emit(data)
135
140
  }
136
141
 
137
- public func onInspectionComplete() {
138
- var data = JSObject()
139
- data["type"] = "onInspectionComplete"
142
+ private func emit(_ data: JSObject) {
143
+ let fields = data.keys.sorted().filter { $0 != "type" && $0 != "inspectionJSON" }
144
+ .map { "\($0)=\(data[$0] ?? "")" }.joined(separator: " ")
145
+ print("Record360Event \(data["type"] ?? "") \(fields)")
140
146
  notifyListeners("Record360Event", data: data)
141
- self.dismissSDKViewController(animated: true, completion: {})
142
147
  }
143
-
144
- public func onInspectionCanceled() {
148
+
149
+ private func inspectionEvent(_ type: String, _ refNum: String, _ nonce: String) -> JSObject {
145
150
  var data = JSObject()
146
- data["type"] = "onInspectionCancelled"
147
- notifyListeners("Record360Event", data: data)
148
- self.dismissSDKViewController(animated: true, completion: {})
151
+ data["type"] = type
152
+ data["referenceNumber"] = refNum
153
+ data["inspectionNonce"] = nonce
154
+ return data
149
155
  }
150
-
151
- public func onInspectionUploadDeleted(forReferenceNumber referenceNumber: String) {
152
-
156
+
157
+ public func onInspectionStarted(forReferenceNumber refNum: String, inspectionNonce nonce: String) {
158
+ emit(inspectionEvent("onInspectionStarted", refNum, nonce))
159
+ }
160
+
161
+ public func onInspectionComplete(forReferenceNumber refNum: String, inspectionNonce nonce: String) {
162
+ emit(inspectionEvent("onInspectionComplete", refNum, nonce))
153
163
  }
154
164
 
155
- public func userHasRequestedToExitRecord360() {
165
+ public func onInspectionCancelled(forReferenceNumber refNum: String, inspectionNonce nonce: String) {
166
+ emit(inspectionEvent("onInspectionCancelled", refNum, nonce))
167
+ }
168
+
169
+ public func onSDKShouldExit() {
170
+ var data = JSObject()
171
+ data["type"] = "onSDKShouldExit"
172
+ emit(data)
156
173
  self.dismissSDKViewController(animated: true, completion: {})
157
174
  }
158
-
159
- public func onInspectionUploaded(forReferenceNumber referenceNumber: String, inspectionJSON: [AnyHashable : Any]) {
175
+
176
+ public func onSDKShouldRelaunch() {
160
177
  var data = JSObject()
161
- if let inspection = inspectionJSON["transaction"] as? [AnyHashable : Any] {
162
- data["inspectionJSON"] = self.dictionaryToJSONString(inspection)!
178
+ data["type"] = "onSDKShouldRelaunch"
179
+ emit(data)
180
+ let relaunch = self.lastLaunch
181
+ self.dismissSDKViewController(animated: true) {
182
+ relaunch?()
163
183
  }
164
- data["type"] = "onInspectionUploaded"
165
- data["referenceNumber"] = referenceNumber
166
- notifyListeners("Record360Event", data: data)
167
184
  }
168
185
 
169
- public func onInspectionUploadFailed(forReferenceNumber referenceNumber: String) {
170
- var data = JSObject()
171
- data["type"] = "onInspectionUploadFailed"
172
- data["referenceNumber"] = referenceNumber
173
- notifyListeners("Record360Event", data: data)
186
+ public func onInspectionUploadDeleted(forReferenceNumber refNum: String, inspectionNonce nonce: String) {
187
+ emit(inspectionEvent("onInspectionUploadDeleted", refNum, nonce))
174
188
  }
175
189
 
190
+ public func onInspectionUploaded(forReferenceNumber refNum: String, inspectionNonce nonce: String, inspectionJSON: [AnyHashable : Any]) {
191
+ var data = inspectionEvent("onInspectionUploaded", refNum, nonce)
192
+ if let json = self.dictionaryToJSONString(inspectionJSON) {
193
+ data["inspectionJSON"] = json
194
+ }
195
+ emit(data)
196
+ }
197
+
198
+ public func onInspectionUploadFailed(forReferenceNumber refNum: String, inspectionNonce nonce: String, error: any Error) {
199
+ var data = inspectionEvent("onInspectionUploadFailed", refNum, nonce)
200
+ data["error"] = error.localizedDescription
201
+ emit(data)
202
+ }
203
+
204
+ public func onInspectionUploadProgress(forReferenceNumber refNum: String, inspectionNonce nonce: String, percentComplete: CGFloat) {
205
+ var data = inspectionEvent("onInspectionUploadProgress", refNum, nonce)
206
+ data["percentComplete"] = Double(percentComplete)
207
+ emit(data)
208
+ }
209
+
176
210
  func dictionaryToJSONString(_ dict: [AnyHashable: Any]) -> String? {
177
211
  do {
178
212
  // Check if the dictionary is valid for JSON serialization
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-record360sdk",
3
- "version": "8.25.0",
3
+ "version": "8.30.1",
4
4
  "description": "Capacitor wrapper for Record360SDK",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
@@ -46,11 +46,11 @@
46
46
  "prepublishOnly": "npm run build"
47
47
  },
48
48
  "devDependencies": {
49
- "@capacitor/android": "^8.3.1",
50
- "@capacitor/cli": "^8.3.1",
51
- "@capacitor/core": "^8.3.1",
49
+ "@capacitor/android": "^8.4.0",
50
+ "@capacitor/cli": "^8.4.0",
51
+ "@capacitor/core": "^8.4.0",
52
52
  "@capacitor/docgen": "^0.2.2",
53
- "@capacitor/ios": "^8.3.1",
53
+ "@capacitor/ios": "^8.4.0",
54
54
  "@ionic/eslint-config": "^0.4.0",
55
55
  "@ionic/prettier-config": "^4.0.0",
56
56
  "@ionic/swiftlint-config": "^2.0.0",
@@ -63,7 +63,7 @@
63
63
  "typescript": "~4.1.5"
64
64
  },
65
65
  "peerDependencies": {
66
- "@capacitor/core": "^8.3.1"
66
+ "@capacitor/core": "^8.4.0"
67
67
  },
68
68
  "prettier": "@ionic/prettier-config",
69
69
  "swiftlint": "@ionic/swiftlint-config",