@doorstepai/dropoff-sdk 2.0.2 → 2.0.5

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 (47) hide show
  1. package/android/build.gradle +1 -1
  2. package/android/src/main/java/com/doorstepai/dropoffsdk/DoorstepAIModule.kt +43 -58
  3. package/ios/DoorstepAI.mm +14 -5
  4. package/ios/DoorstepAI.swift +53 -18
  5. package/ios/DoorstepDropoffSDK.xcframework/Info.plist +5 -5
  6. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/DoorstepDropoffSDK +0 -0
  7. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Headers/DoorstepDropoffSDK.h +1 -0
  8. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Headers/RateReducer.h +117 -0
  9. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Info.plist +0 -0
  10. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.abi.json +2341 -839
  11. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.private.swiftinterface +24 -24
  12. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  13. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.swiftinterface +24 -24
  14. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/PrivacyInfo.xcprivacy +39 -0
  15. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/_CodeSignature/CodeResources +35 -13
  16. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/DWARF/DoorstepDropoffSDK +0 -0
  17. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/DoorstepDropoffSDK.yml +2103 -1462
  18. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/DoorstepDropoffSDK +0 -0
  19. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Headers/DoorstepDropoffSDK.h +1 -0
  20. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Headers/RateReducer.h +117 -0
  21. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Info.plist +0 -0
  22. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.abi.json +2341 -839
  23. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +24 -24
  24. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  25. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.swiftinterface +24 -24
  26. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json +2341 -839
  27. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +24 -24
  28. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  29. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +24 -24
  30. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/PrivacyInfo.xcprivacy +39 -0
  31. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/_CodeSignature/CodeResources +45 -23
  32. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/DWARF/DoorstepDropoffSDK +0 -0
  33. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/DoorstepDropoffSDK.yml +2103 -1462
  34. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/Relocations/x86_64/DoorstepDropoffSDK.yml +2093 -1457
  35. package/lib/module/DoorstepAI.js +91 -27
  36. package/lib/module/DoorstepAI.js.map +1 -1
  37. package/lib/module/RootDoorstepAI.js.map +1 -1
  38. package/lib/module/index.js.map +1 -1
  39. package/lib/typescript/src/DoorstepAI.d.ts +65 -5
  40. package/lib/typescript/src/DoorstepAI.d.ts.map +1 -1
  41. package/lib/typescript/src/RootDoorstepAI.d.ts.map +1 -1
  42. package/lib/typescript/src/index.d.ts +1 -0
  43. package/lib/typescript/src/index.d.ts.map +1 -1
  44. package/package.json +1 -1
  45. package/src/DoorstepAI.tsx +260 -51
  46. package/src/RootDoorstepAI.tsx +0 -1
  47. package/src/index.tsx +6 -0
@@ -86,7 +86,7 @@ def kotlin_version = getExtOrDefault("kotlinVersion")
86
86
  dependencies {
87
87
  implementation "com.facebook.react:react-android"
88
88
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
89
- implementation("ai.doorstep.com:doorstepai-dropoff-sdk:2.0.1")
89
+ implementation("ai.doorstep.com:doorstepai-dropoff-sdk:2.0.6")
90
90
  api "org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1"
91
91
  }
92
92
 
@@ -9,6 +9,7 @@ import com.facebook.react.bridge.Promise
9
9
  import com.doorstepai.sdks.tracking.DoorstepAI
10
10
  import com.doorstepai.sdks.tracking.AddressType
11
11
  import com.doorstepai.sdks.tracking.DropoffType
12
+ import com.doorstepai.sdks.tracking.LatLngObject
12
13
  import com.facebook.react.bridge.ReadableMap
13
14
  import kotlinx.coroutines.Dispatchers
14
15
  import kotlinx.coroutines.CoroutineScope
@@ -42,10 +43,18 @@ class DoorstepAIModule(private val reactContext: ReactApplicationContext) :
42
43
  placeID: String,
43
44
  deliveryId: String,
44
45
  timeoutSeconds: Double?,
46
+ autoStopAfterDropoffSeconds: Double?,
47
+ manualForeground: Boolean?,
45
48
  promise: Promise
46
49
  ) {
47
50
  try {
48
- DoorstepAI.startDeliveryByPlaceID(placeID, deliveryId, timeoutSeconds) { result ->
51
+ DoorstepAI.startDeliveryByPlaceID(
52
+ placeID = placeID,
53
+ deliveryId = deliveryId,
54
+ timeoutSeconds = timeoutSeconds,
55
+ manualForeground = manualForeground ?: false,
56
+ autoStopAfterDropoffSeconds = autoStopAfterDropoffSeconds
57
+ ) { result ->
49
58
  result.onSuccess { sessionId ->
50
59
  promise.resolve(sessionId)
51
60
  }.onFailure { error ->
@@ -81,11 +90,22 @@ class DoorstepAIModule(private val reactContext: ReactApplicationContext) :
81
90
  fun startDeliveryByAddressString(
82
91
  address: String,
83
92
  deliveryId: String,
93
+ coordinates: ReadableMap?,
84
94
  timeoutSeconds: Double?,
95
+ autoStopAfterDropoffSeconds: Double?,
96
+ manualForeground: Boolean?,
85
97
  promise: Promise
86
98
  ) {
87
99
  try {
88
- DoorstepAI.startDeliveryByAddressString(address, deliveryId, timeoutSeconds) { result ->
100
+ val coords = parseCoordinates(coordinates)
101
+ DoorstepAI.startDeliveryByAddressString(
102
+ address = address,
103
+ deliveryId = deliveryId,
104
+ coordinates = coords,
105
+ timeoutSeconds = timeoutSeconds,
106
+ manualForeground = manualForeground ?: false,
107
+ autoStopAfterDropoffSeconds = autoStopAfterDropoffSeconds
108
+ ) { result ->
89
109
  result.onSuccess { message ->
90
110
  promise.resolve(message)
91
111
  }.onFailure { error ->
@@ -123,7 +143,10 @@ class DoorstepAIModule(private val reactContext: ReactApplicationContext) :
123
143
  fun startDeliveryByAddress(
124
144
  addressMap: ReadableMap,
125
145
  deliveryId: String,
146
+ coordinates: ReadableMap?,
126
147
  timeoutSeconds: Double?,
148
+ autoStopAfterDropoffSeconds: Double?,
149
+ manualForeground: Boolean?,
127
150
  promise: Promise
128
151
  ) {
129
152
  try {
@@ -143,7 +166,15 @@ class DoorstepAIModule(private val reactContext: ReactApplicationContext) :
143
166
  postalCode = postalCode
144
167
  )
145
168
 
146
- DoorstepAI.startDeliveryByAddressType(address, deliveryId, timeoutSeconds) { result ->
169
+ val coords = parseCoordinates(coordinates)
170
+ DoorstepAI.startDeliveryByAddressType(
171
+ address = address,
172
+ deliveryId = deliveryId,
173
+ coordinates = coords,
174
+ timeoutSeconds = timeoutSeconds,
175
+ manualForeground = manualForeground ?: false,
176
+ autoStopAfterDropoffSeconds = autoStopAfterDropoffSeconds
177
+ ) { result ->
147
178
  result.onSuccess { sessionId ->
148
179
  promise.resolve(sessionId)
149
180
  }.onFailure { error ->
@@ -196,8 +227,9 @@ class DoorstepAIModule(private val reactContext: ReactApplicationContext) :
196
227
  }
197
228
 
198
229
  @ReactMethod(isBlockingSynchronousMethod = true)
199
- fun setApiKey(key: String) {
230
+ fun setApiKey(key: String): Boolean {
200
231
  DoorstepAI.setAPIKey(key)
232
+ return true
201
233
  }
202
234
 
203
235
  @ReactMethod
@@ -224,60 +256,6 @@ class DoorstepAIModule(private val reactContext: ReactApplicationContext) :
224
256
  }
225
257
  }
226
258
 
227
- @ReactMethod
228
- fun hasCachedData(promise: Promise) {
229
- CoroutineScope(Dispatchers.IO).launch {
230
- try {
231
- val result = DoorstepAI.hasCachedData()
232
- promise.resolve(result)
233
- } catch (e: Exception) {
234
- promise.reject("HAS_CACHED_DATA_ERROR", e.message ?: "Failed to check cached data")
235
- }
236
- }
237
- }
238
-
239
- @ReactMethod
240
- fun waitForCachedDataCompletion(promise: Promise) {
241
- CoroutineScope(Dispatchers.IO).launch {
242
- try {
243
- val result = DoorstepAI.waitForCachedDataCompletion()
244
- promise.resolve(result)
245
- } catch (e: Exception) {
246
- promise.reject("WAIT_CACHED_DATA_ERROR", e.message ?: "Failed while waiting for cached data completion")
247
- }
248
- }
249
- }
250
-
251
- @ReactMethod
252
- fun isCacheProcessingInProgress(promise: Promise) {
253
- try {
254
- val result = DoorstepAI.isCacheProcessingInProgress()
255
- promise.resolve(result)
256
- } catch (e: Exception) {
257
- promise.reject("CACHE_PROCESSING_STATUS_ERROR", e.message ?: "Failed to check cache processing status")
258
- }
259
- }
260
-
261
- @ReactMethod
262
- fun hasPendingNetworkRequests(promise: Promise) {
263
- try {
264
- val result = DoorstepAI.hasPendingNetworkRequests()
265
- promise.resolve(result)
266
- } catch (e: Exception) {
267
- promise.reject("PENDING_NETWORK_REQUESTS_ERROR", e.message ?: "Failed to check pending network requests")
268
- }
269
- }
270
-
271
- @ReactMethod
272
- fun getPendingNetworkRequestsCount(promise: Promise) {
273
- try {
274
- val result = DoorstepAI.getPendingNetworkRequestsCount()
275
- promise.resolve(result)
276
- } catch (e: Exception) {
277
- promise.reject("PENDING_NETWORK_REQUESTS_COUNT_ERROR", e.message ?: "Failed to get pending network requests count")
278
- }
279
- }
280
-
281
259
  @ReactMethod
282
260
  fun disableDevMode(promise: Promise) {
283
261
  try {
@@ -288,6 +266,13 @@ class DoorstepAIModule(private val reactContext: ReactApplicationContext) :
288
266
  }
289
267
  }
290
268
 
269
+ private fun parseCoordinates(map: ReadableMap?): LatLngObject? {
270
+ if (map == null) return null
271
+ val lat = if (map.hasKey("lat")) map.getDouble("lat") else return null
272
+ val lng = if (map.hasKey("lng")) map.getDouble("lng") else return null
273
+ return LatLngObject(lat = lat, lng = lng)
274
+ }
275
+
291
276
  companion object {
292
277
  const val NAME = "DoorstepAI"
293
278
  }
package/ios/DoorstepAI.mm CHANGED
@@ -3,27 +3,39 @@
3
3
  @interface RCT_EXTERN_MODULE(DoorstepAI, NSObject)
4
4
 
5
5
  RCT_EXTERN_METHOD(setApiKey:(nonnull NSString *)apiKey)
6
+ RCT_EXTERN_METHOD(requestAllPermissions:(BOOL)requestAlwaysLocation)
7
+ RCT_EXTERN_METHOD(configureRemoteLogging:(BOOL)enabled
8
+ minLevel:(nullable NSNumber *)minLevel
9
+ flushIntervalSeconds:(nullable NSNumber *)flushIntervalSeconds
10
+ batchSize:(nullable NSNumber *)batchSize
11
+ maxQueueSize:(nullable NSNumber *)maxQueueSize)
6
12
  RCT_EXTERN_METHOD(enableDevMode:(nonnull NSString *)apiKey
7
13
  resolver:(RCTPromiseResolveBlock)resolve
8
14
  rejecter:(RCTPromiseRejectBlock)reject)
9
15
  RCT_EXTERN_METHOD(startDeliveryByPlaceID:(nonnull NSString *)placeID
10
16
  deliveryId:(nonnull NSString *)deliveryId
11
17
  timeoutSeconds:(nullable NSNumber *)timeoutSeconds
18
+ autoStopAfterDropoffSeconds:(nullable NSNumber *)autoStopAfterDropoffSeconds
12
19
  resolver:(RCTPromiseResolveBlock)resolve
13
20
  rejecter:(RCTPromiseRejectBlock)reject)
14
21
  RCT_EXTERN_METHOD(startDeliveryByPlusCode:(nonnull NSString *)plusCode
15
22
  deliveryId:(nonnull NSString *)deliveryId
16
23
  timeoutSeconds:(nullable NSNumber *)timeoutSeconds
24
+ autoStopAfterDropoffSeconds:(nullable NSNumber *)autoStopAfterDropoffSeconds
17
25
  resolver:(RCTPromiseResolveBlock)resolve
18
26
  rejecter:(RCTPromiseRejectBlock)reject)
19
27
  RCT_EXTERN_METHOD(startDeliveryByAddress:(nonnull NSDictionary *)address
20
28
  deliveryId:(nonnull NSString *)deliveryId
29
+ coordinates:(nullable NSDictionary *)coordinates
21
30
  timeoutSeconds:(nullable NSNumber *)timeoutSeconds
31
+ autoStopAfterDropoffSeconds:(nullable NSNumber *)autoStopAfterDropoffSeconds
22
32
  resolver:(RCTPromiseResolveBlock)resolve
23
33
  rejecter:(RCTPromiseRejectBlock)reject)
24
34
  RCT_EXTERN_METHOD(startDeliveryByAddressString:(nonnull NSString *)address
25
35
  deliveryId:(nonnull NSString *)deliveryId
36
+ coordinates:(nullable NSDictionary *)coordinates
26
37
  timeoutSeconds:(nullable NSNumber *)timeoutSeconds
38
+ autoStopAfterDropoffSeconds:(nullable NSNumber *)autoStopAfterDropoffSeconds
27
39
  resolver:(RCTPromiseResolveBlock)resolve
28
40
  rejecter:(RCTPromiseRejectBlock)reject)
29
41
  RCT_EXTERN_METHOD(startDeliveryByLatLng:(nonnull NSNumber *)latitude
@@ -31,6 +43,7 @@ RCT_EXTERN_METHOD(startDeliveryByLatLng:(nonnull NSNumber *)latitude
31
43
  subUnit:(nonnull NSString *)subUnit
32
44
  deliveryId:(nonnull NSString *)deliveryId
33
45
  timeoutSeconds:(nullable NSNumber *)timeoutSeconds
46
+ autoStopAfterDropoffSeconds:(nullable NSNumber *)autoStopAfterDropoffSeconds
34
47
  resolver:(RCTPromiseResolveBlock)resolve
35
48
  rejecter:(RCTPromiseRejectBlock)reject)
36
49
  RCT_EXTERN_METHOD(newEvent:(nonnull NSString *)eventName
@@ -44,9 +57,5 @@ RCT_EXTERN_METHOD(markDropoff:(nonnull NSString *)deliveryId
44
57
  RCT_EXTERN_METHOD(stopDelivery:(nonnull NSString *)deliveryId
45
58
  resolver:(RCTPromiseResolveBlock)resolve
46
59
  rejecter:(RCTPromiseRejectBlock)reject)
47
- RCT_EXTERN_METHOD(hasCachedData:(RCTPromiseResolveBlock)resolve
48
- rejecter:(RCTPromiseRejectBlock)reject)
49
- RCT_EXTERN_METHOD(waitForCacheDataCompletion:(RCTPromiseResolveBlock)resolve
50
- rejecter:(RCTPromiseRejectBlock)reject)
51
60
 
52
- @end
61
+ @end
@@ -24,20 +24,44 @@ class DoorstepAIBridge: NSObject {
24
24
  DoorstepAI.setApiKey(key: apiKey)
25
25
  }
26
26
 
27
+ @objc
28
+ func requestAllPermissions(_ requestAlwaysLocation: Bool) {
29
+ DoorstepAI.requestAllPermissions(requestAlwaysLocation: requestAlwaysLocation)
30
+ }
31
+
32
+ @objc
33
+ func configureRemoteLogging(_ enabled: Bool,
34
+ minLevel: NSNumber?,
35
+ flushIntervalSeconds: NSNumber?,
36
+ batchSize: NSNumber?,
37
+ maxQueueSize: NSNumber?) {
38
+ let level = minLevel.flatMap { SDKLogLevel(rawValue: $0.intValue) } ?? .warning
39
+ DoorstepAI.configureRemoteLogging(
40
+ enabled: enabled,
41
+ minLevel: level,
42
+ flushInterval: flushIntervalSeconds?.doubleValue ?? 30,
43
+ batchSize: batchSize?.intValue ?? 50,
44
+ maxQueueSize: maxQueueSize?.intValue ?? 1000
45
+ )
46
+ }
47
+
27
48
  @objc
28
49
  func startDeliveryByPlaceID(_ placeID: NSString,
29
50
  deliveryId: NSString,
30
51
  timeoutSeconds: NSNumber?,
52
+ autoStopAfterDropoffSeconds: NSNumber?,
31
53
  resolver resolve: @escaping RCTPromiseResolveBlock,
32
54
  rejecter reject: @escaping RCTPromiseRejectBlock) {
33
55
  // Use Swift's concurrency support to call the async method.
34
56
  Task {
35
57
  do {
36
58
  let timeout = timeoutSeconds?.doubleValue
59
+ let autoStop = autoStopAfterDropoffSeconds?.doubleValue
37
60
  try await DoorstepAI.startDeliveryByPlaceID(
38
61
  placeID: placeID as String,
39
62
  deliveryId: deliveryId as String,
40
- timeoutSeconds: timeout
63
+ timeoutSeconds: timeout,
64
+ autoStopAfterDropoffSeconds: autoStop
41
65
  )
42
66
  resolve(nil)
43
67
  } catch {
@@ -50,15 +74,18 @@ class DoorstepAIBridge: NSObject {
50
74
  func startDeliveryByPlusCode(_ plusCode: NSString,
51
75
  deliveryId: NSString,
52
76
  timeoutSeconds: NSNumber?,
77
+ autoStopAfterDropoffSeconds: NSNumber?,
53
78
  resolver resolve: @escaping RCTPromiseResolveBlock,
54
79
  rejecter reject: @escaping RCTPromiseRejectBlock) {
55
80
  Task {
56
81
  do {
57
82
  let timeout = timeoutSeconds?.doubleValue
83
+ let autoStop = autoStopAfterDropoffSeconds?.doubleValue
58
84
  try await DoorstepAI.startDeliveryByPlusCode(
59
85
  plusCode: plusCode as String,
60
86
  deliveryId: deliveryId as String,
61
- timeoutSeconds: timeout
87
+ timeoutSeconds: timeout,
88
+ autoStopAfterDropoffSeconds: autoStop
62
89
  )
63
90
  resolve(nil)
64
91
  } catch {
@@ -70,16 +97,22 @@ class DoorstepAIBridge: NSObject {
70
97
  @objc
71
98
  func startDeliveryByAddressString(_ address: NSString,
72
99
  deliveryId: NSString,
100
+ coordinates: NSDictionary?,
73
101
  timeoutSeconds: NSNumber?,
102
+ autoStopAfterDropoffSeconds: NSNumber?,
74
103
  resolver resolve: @escaping RCTPromiseResolveBlock,
75
104
  rejecter reject: @escaping RCTPromiseRejectBlock) {
76
105
  Task {
77
106
  do {
78
107
  let timeout = timeoutSeconds?.doubleValue
108
+ let autoStop = autoStopAfterDropoffSeconds?.doubleValue
109
+ let coords = parseCoordinates(coordinates)
79
110
  try await DoorstepAI.startDeliveryByAddressString(
80
111
  address: address as String,
81
112
  deliveryId: deliveryId as String,
82
- timeoutSeconds: timeout
113
+ coordinates: coords,
114
+ timeoutSeconds: timeout,
115
+ autoStopAfterDropoffSeconds: autoStop
83
116
  )
84
117
  resolve(nil)
85
118
  } catch {
@@ -94,17 +127,20 @@ class DoorstepAIBridge: NSObject {
94
127
  subUnit: NSString,
95
128
  deliveryId: NSString,
96
129
  timeoutSeconds: NSNumber?,
130
+ autoStopAfterDropoffSeconds: NSNumber?,
97
131
  resolver resolve: @escaping RCTPromiseResolveBlock,
98
132
  rejecter reject: @escaping RCTPromiseRejectBlock) {
99
133
  Task {
100
134
  do {
101
135
  let timeout = timeoutSeconds?.doubleValue
136
+ let autoStop = autoStopAfterDropoffSeconds?.doubleValue
102
137
  try await DoorstepAI.startDeliveryByLatLng(
103
138
  latitude: latitude.doubleValue,
104
139
  longitude: longitude.doubleValue,
105
140
  subUnit: subUnit as String,
106
141
  deliveryId: deliveryId as String,
107
- timeoutSeconds: timeout
142
+ timeoutSeconds: timeout,
143
+ autoStopAfterDropoffSeconds: autoStop
108
144
  )
109
145
  resolve(nil)
110
146
  } catch {
@@ -116,11 +152,12 @@ class DoorstepAIBridge: NSObject {
116
152
  @objc
117
153
  func startDeliveryByAddress(_ address: [String: Any],
118
154
  deliveryId: NSString,
155
+ coordinates: NSDictionary?,
119
156
  timeoutSeconds: NSNumber?,
157
+ autoStopAfterDropoffSeconds: NSNumber?,
120
158
  resolver resolve: @escaping RCTPromiseResolveBlock,
121
159
  rejecter reject: @escaping RCTPromiseRejectBlock) {
122
160
  Task {
123
- print("Starting delivery by address: \(address)")
124
161
  do {
125
162
  guard let streetNumber = address["streetNumber"] as? String,
126
163
  let route = address["route"] as? String,
@@ -140,10 +177,14 @@ class DoorstepAIBridge: NSObject {
140
177
  postalCode: postalCode)
141
178
 
142
179
  let timeout = timeoutSeconds?.doubleValue
180
+ let autoStop = autoStopAfterDropoffSeconds?.doubleValue
181
+ let coords = parseCoordinates(coordinates)
143
182
  try await DoorstepAI.startDeliveryByAddressType(
144
183
  address: addressStruct,
145
184
  deliveryId: deliveryId as String,
146
- timeoutSeconds: timeout
185
+ coordinates: coords,
186
+ timeoutSeconds: timeout,
187
+ autoStopAfterDropoffSeconds: autoStop
147
188
  )
148
189
  resolve(nil)
149
190
  } catch let error as DoorstepAIError {
@@ -206,19 +247,13 @@ class DoorstepAIBridge: NSObject {
206
247
  }
207
248
  }
208
249
 
209
- @objc
210
- func hasCachedData(_ resolve: @escaping RCTPromiseResolveBlock,
211
- rejecter reject: @escaping RCTPromiseRejectBlock) {
212
- resolve(DoorstepAI.hasCachedData())
213
- }
214
-
215
- @objc
216
- func waitForCacheDataCompletion(_ resolve: @escaping RCTPromiseResolveBlock,
217
- rejecter reject: @escaping RCTPromiseRejectBlock) {
218
- Task {
219
- let result = await DoorstepAI.waitForCacheDataCompletion()
220
- resolve(result)
250
+ private func parseCoordinates(_ raw: NSDictionary?) -> LatLngObject? {
251
+ guard let coordinates = raw as? [String: Any],
252
+ let lat = coordinates["lat"] as? Double,
253
+ let lng = coordinates["lng"] as? Double else {
254
+ return nil
221
255
  }
256
+ return LatLngObject(lat: lat, lng: lng)
222
257
  }
223
258
 
224
259
  }
@@ -10,15 +10,18 @@
10
10
  <key>DebugSymbolsPath</key>
11
11
  <string>dSYMs</string>
12
12
  <key>LibraryIdentifier</key>
13
- <string>ios-arm64</string>
13
+ <string>ios-arm64_x86_64-simulator</string>
14
14
  <key>LibraryPath</key>
15
15
  <string>DoorstepDropoffSDK.framework</string>
16
16
  <key>SupportedArchitectures</key>
17
17
  <array>
18
18
  <string>arm64</string>
19
+ <string>x86_64</string>
19
20
  </array>
20
21
  <key>SupportedPlatform</key>
21
22
  <string>ios</string>
23
+ <key>SupportedPlatformVariant</key>
24
+ <string>simulator</string>
22
25
  </dict>
23
26
  <dict>
24
27
  <key>BinaryPath</key>
@@ -26,18 +29,15 @@
26
29
  <key>DebugSymbolsPath</key>
27
30
  <string>dSYMs</string>
28
31
  <key>LibraryIdentifier</key>
29
- <string>ios-arm64_x86_64-simulator</string>
32
+ <string>ios-arm64</string>
30
33
  <key>LibraryPath</key>
31
34
  <string>DoorstepDropoffSDK.framework</string>
32
35
  <key>SupportedArchitectures</key>
33
36
  <array>
34
37
  <string>arm64</string>
35
- <string>x86_64</string>
36
38
  </array>
37
39
  <key>SupportedPlatform</key>
38
40
  <string>ios</string>
39
- <key>SupportedPlatformVariant</key>
40
- <string>simulator</string>
41
41
  </dict>
42
42
  </array>
43
43
  <key>CFBundlePackageType</key>
@@ -14,5 +14,6 @@ FOUNDATION_EXPORT double DoorstepDropoffSDKVersionNumber;
14
14
  FOUNDATION_EXPORT const unsigned char DoorstepDropoffSDKVersionString[];
15
15
 
16
16
  // In this header, you should import all the public headers of your framework using statements like #import <DoorstepDropoffSDK/PublicHeader.h>
17
+ #import <DoorstepDropoffSDK/RateReducer.h>
17
18
 
18
19
 
@@ -0,0 +1,117 @@
1
+ /**
2
+ * @file RateReducer.h
3
+ *
4
+ * Pure-C IMU rate reducer — port of the strapdown coning/sculling algorithm
5
+ * in the legacy C++ RateReducer. Designed for integration into the
6
+ * DoorstepDropoffSDK sensor pipeline via SensorRateReducer.swift.
7
+ *
8
+ * Channel treatment:
9
+ * - rotationRate / rawGyro → coning-corrected integration (delta-angle)
10
+ * - accel / userAccel → sculling-corrected integration (delta-velocity)
11
+ * - gravity / roll,pitch,yaw → simple per-sample average over the epoch
12
+ * - mag / heading / proximity → latest-value pass-through
13
+ *
14
+ * NOT compiled into the Xcode target by default; add RateReducer.c to the
15
+ * framework target if you want to call these functions from Objective-C.
16
+ * The active Swift implementation in SensorRateReducer.swift mirrors this
17
+ * code exactly and requires no project-file changes.
18
+ */
19
+
20
+ #pragma once
21
+ #include <stdbool.h>
22
+
23
+ #ifdef __cplusplus
24
+ extern "C" {
25
+ #endif
26
+
27
+ typedef struct { double x, y, z; } rr_vec3_t;
28
+
29
+ /** Flat sample type — mirrors the fields of InternalSensorData. */
30
+ typedef struct {
31
+ /* Inertial channels (coning/sculling-integrated, then rate-recovered) */
32
+ double rotation_rate_x, rotation_rate_y, rotation_rate_z;
33
+ double accel_x, accel_y, accel_z;
34
+ double raw_gyro_x, raw_gyro_y, raw_gyro_z;
35
+ double user_accel_x, user_accel_y, user_accel_z;
36
+
37
+ /* Averaged over the epoch */
38
+ double gravity_x, gravity_y, gravity_z;
39
+ double roll, pitch, yaw;
40
+
41
+ /* Latest-value pass-through */
42
+ double mag_x, mag_y, mag_z;
43
+ int mag_accuracy;
44
+ double raw_mag_x, raw_mag_y, raw_mag_z;
45
+ double heading;
46
+ int proximity_state; /* 0 = false, 1 = true */
47
+
48
+ /* Timing */
49
+ double timestamp; /* wall-clock timestamp of the epoch's last sample */
50
+ double delta_time; /* total epoch duration in seconds */
51
+ } rr_sample_t;
52
+
53
+ /** Per-pair integration state for one (gyro, accel) channel pair. */
54
+ typedef struct {
55
+ rr_vec3_t sum_delta_theta; /* accumulated angular increments */
56
+ rr_vec3_t prev_delta_theta; /* last sample's delta — NOT reset across epochs */
57
+ rr_vec3_t coning; /* coning correction accumulator */
58
+
59
+ rr_vec3_t sum_delta_vel; /* accumulated velocity increments */
60
+ rr_vec3_t prev_delta_vel; /* last sample's delta — NOT reset across epochs */
61
+ rr_vec3_t sculling; /* sculling correction accumulator */
62
+ } rr_pair_state_t;
63
+
64
+ /** Top-level rate-reducer state. Zero-initialise before calling rr_init(). */
65
+ typedef struct {
66
+ rr_pair_state_t primary; /* fusion gyro (rotationRate) + fusion accel */
67
+ rr_pair_state_t raw; /* raw gyro + raw accel (includes gravity) */
68
+
69
+ rr_vec3_t sum_gravity;
70
+ double sum_roll, sum_pitch, sum_yaw;
71
+
72
+ rr_sample_t latest; /* latest-value fields, refreshed every sample */
73
+
74
+ double sum_delta_time;
75
+ double prev_timestamp; /* 0.0 = not yet seen a sample */
76
+ double nominal_input_dt; /* 1/inputHz — fallback when timestamps are missing */
77
+ int count; /* samples accumulated in the current epoch */
78
+ int n; /* target samples per output epoch */
79
+
80
+ bool output_ready;
81
+ rr_sample_t output;
82
+ } rr_state_t;
83
+
84
+ /**
85
+ * Initialise the rate reducer.
86
+ *
87
+ * @param rr Pointer to a zero-initialised rr_state_t.
88
+ * @param input_hz Sensor input rate (e.g. 100.0).
89
+ * @param output_hz Desired output rate (e.g. 50.0).
90
+ * n = round(input_hz / output_hz), clamped to [2, 100].
91
+ */
92
+ void rr_init(rr_state_t *rr, double input_hz, double output_hz);
93
+
94
+ /**
95
+ * Feed one input sample.
96
+ *
97
+ * @return true when an output sample is ready; retrieve it with rr_get_output().
98
+ */
99
+ bool rr_process(rr_state_t *rr, const rr_sample_t *sample);
100
+
101
+ /**
102
+ * Retrieve the pending output sample.
103
+ *
104
+ * @return true if a sample was available; false if rr_process() has not yet
105
+ * returned true since the last retrieval.
106
+ */
107
+ bool rr_get_output(rr_state_t *rr, rr_sample_t *out);
108
+
109
+ /**
110
+ * Change the decimation factor at runtime.
111
+ * Epoch-in-progress is discarded; prev_delta_* state is preserved for continuity.
112
+ */
113
+ void rr_set_n(rr_state_t *rr, int n);
114
+
115
+ #ifdef __cplusplus
116
+ }
117
+ #endif