react-native-bg-geolocation 0.2.0

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 (142) hide show
  1. package/BgGeolocation.podspec +39 -0
  2. package/LICENSE +20 -0
  3. package/README.md +366 -0
  4. package/android/build.gradle +69 -0
  5. package/android/src/main/AndroidManifest.xml +53 -0
  6. package/android/src/main/java/com/bggeolocation/BgGeolocationActivityRecognitionReceiver.kt +116 -0
  7. package/android/src/main/java/com/bggeolocation/BgGeolocationBootReceiver.kt +44 -0
  8. package/android/src/main/java/com/bggeolocation/BgGeolocationForegroundService.kt +373 -0
  9. package/android/src/main/java/com/bggeolocation/BgGeolocationGeofenceReceiver.kt +55 -0
  10. package/android/src/main/java/com/bggeolocation/BgGeolocationHeadlessTask.kt +138 -0
  11. package/android/src/main/java/com/bggeolocation/BgGeolocationModule.kt +1030 -0
  12. package/android/src/main/java/com/bggeolocation/BgGeolocationMotionStateMachine.kt +159 -0
  13. package/android/src/main/java/com/bggeolocation/BgGeolocationPackage.kt +31 -0
  14. package/android/src/main/res/drawable/bg_geo_notification.xml +9 -0
  15. package/ios/BgGeolocation.h +14 -0
  16. package/ios/BgGeolocation.mm +709 -0
  17. package/ios/engine/AtomicBoolean.swift +48 -0
  18. package/ios/engine/BGActivityChangeEvent.swift +20 -0
  19. package/ios/engine/BGActivityConfig.swift +71 -0
  20. package/ios/engine/BGAppConfig.swift +92 -0
  21. package/ios/engine/BGAppState.swift +147 -0
  22. package/ios/engine/BGAuthorization.swift +85 -0
  23. package/ios/engine/BGAuthorizationAlertPresenter.swift +39 -0
  24. package/ios/engine/BGAuthorizationConfig.swift +50 -0
  25. package/ios/engine/BGAuthorizationEvent.swift +40 -0
  26. package/ios/engine/BGBackgroundTaskManager.swift +143 -0
  27. package/ios/engine/BGCLRouter.swift +101 -0
  28. package/ios/engine/BGCallback.swift +19 -0
  29. package/ios/engine/BGConfig.swift +440 -0
  30. package/ios/engine/BGConfigModuleBase.swift +180 -0
  31. package/ios/engine/BGConfigOLD.swift +582 -0
  32. package/ios/engine/BGConnectivityChangeEvent.swift +15 -0
  33. package/ios/engine/BGCrashDetector.swift +122 -0
  34. package/ios/engine/BGCurrentPositionRequest.swift +87 -0
  35. package/ios/engine/BGDataStore.swift +75 -0
  36. package/ios/engine/BGDatabase.swift +677 -0
  37. package/ios/engine/BGDatabasePool.swift +220 -0
  38. package/ios/engine/BGDatabaseQueue.swift +215 -0
  39. package/ios/engine/BGDateUtils.swift +26 -0
  40. package/ios/engine/BGDeviceInfo.swift +54 -0
  41. package/ios/engine/BGDeviceManager.swift +65 -0
  42. package/ios/engine/BGEnabledChangeEvent.swift +11 -0
  43. package/ios/engine/BGEnv.swift +17 -0
  44. package/ios/engine/BGEventBus.swift +83 -0
  45. package/ios/engine/BGEventManager.swift +169 -0
  46. package/ios/engine/BGEventNames.swift +51 -0
  47. package/ios/engine/BGGeofence.swift +233 -0
  48. package/ios/engine/BGGeofenceDAO.swift +152 -0
  49. package/ios/engine/BGGeofenceEvent.swift +42 -0
  50. package/ios/engine/BGGeofenceLocationRequest.swift +94 -0
  51. package/ios/engine/BGGeofenceManager.swift +315 -0
  52. package/ios/engine/BGGeofenceTransition.swift +97 -0
  53. package/ios/engine/BGGeofencesChangeEvent.swift +26 -0
  54. package/ios/engine/BGGeolocationConfig.swift +136 -0
  55. package/ios/engine/BGHeartbeatEvent.swift +31 -0
  56. package/ios/engine/BGHeartbeatService.swift +51 -0
  57. package/ios/engine/BGHttpConfig.swift +105 -0
  58. package/ios/engine/BGHttpErrorCodes.swift +63 -0
  59. package/ios/engine/BGHttpEvent.swift +34 -0
  60. package/ios/engine/BGHttpRequest.swift +126 -0
  61. package/ios/engine/BGHttpResponse.swift +93 -0
  62. package/ios/engine/BGHttpService.swift +428 -0
  63. package/ios/engine/BGKalmanFilter.swift +105 -0
  64. package/ios/engine/BGLMActionNames.swift +55 -0
  65. package/ios/engine/BGLicenseManager.swift +26 -0
  66. package/ios/engine/BGLiveActivityManager.swift +327 -0
  67. package/ios/engine/BGLocation.swift +311 -0
  68. package/ios/engine/BGLocationAuthorization.swift +427 -0
  69. package/ios/engine/BGLocationDAO.swift +252 -0
  70. package/ios/engine/BGLocationErrors.swift +28 -0
  71. package/ios/engine/BGLocationEvent.swift +43 -0
  72. package/ios/engine/BGLocationFilter.swift +82 -0
  73. package/ios/engine/BGLocationFilterConfig.swift +57 -0
  74. package/ios/engine/BGLocationHelper.swift +54 -0
  75. package/ios/engine/BGLocationManager.swift +662 -0
  76. package/ios/engine/BGLocationMetricsEngine.swift +116 -0
  77. package/ios/engine/BGLocationRequestService.swift +459 -0
  78. package/ios/engine/BGLocationSatisfier.swift +14 -0
  79. package/ios/engine/BGLocationStreamEvent.swift +27 -0
  80. package/ios/engine/BGLog.swift +337 -0
  81. package/ios/engine/BGLogLevel.swift +26 -0
  82. package/ios/engine/BGLoggerConfig.swift +60 -0
  83. package/ios/engine/BGMotionActivity.swift +31 -0
  84. package/ios/engine/BGMotionActivityClassifier.swift +108 -0
  85. package/ios/engine/BGMotionActivityManagerAdapter.swift +40 -0
  86. package/ios/engine/BGMotionActivitySource.swift +46 -0
  87. package/ios/engine/BGMotionDetector.swift +377 -0
  88. package/ios/engine/BGMotionPermissionManager.swift +50 -0
  89. package/ios/engine/BGNativeLogger.swift +48 -0
  90. package/ios/engine/BGNotificaitons.swift +37 -0
  91. package/ios/engine/BGOdometer.swift +66 -0
  92. package/ios/engine/BGPersistenceConfig.swift +29 -0
  93. package/ios/engine/BGPolygonStreamRequest.swift +48 -0
  94. package/ios/engine/BGPowerSaveChangeEvent.swift +12 -0
  95. package/ios/engine/BGPropertySpec.swift +29 -0
  96. package/ios/engine/BGProviderChangeEvent.swift +31 -0
  97. package/ios/engine/BGQueue.swift +50 -0
  98. package/ios/engine/BGRPC.swift +194 -0
  99. package/ios/engine/BGReachability.swift +58 -0
  100. package/ios/engine/BGResultSet.swift +157 -0
  101. package/ios/engine/BGSchedule.swift +228 -0
  102. package/ios/engine/BGScheduleEvent.swift +13 -0
  103. package/ios/engine/BGScheduler.swift +116 -0
  104. package/ios/engine/BGSingleLocationRequest.swift +49 -0
  105. package/ios/engine/BGStreamLocationRequest.swift +42 -0
  106. package/ios/engine/BGTemplate.swift +54 -0
  107. package/ios/engine/BGTimerService.swift +46 -0
  108. package/ios/engine/BGTrackingAudioManager.swift +286 -0
  109. package/ios/engine/BGTrackingService.swift +879 -0
  110. package/ios/engine/BGWatchPositionRequest.swift +63 -0
  111. package/ios/engine/DatabaseQueue.swift +47 -0
  112. package/ios/engine/LogQuery.swift +10 -0
  113. package/ios/engine/SQLQuery.swift +65 -0
  114. package/ios/engine/TransistorAuthorizationToken.swift +182 -0
  115. package/ios/liveactivity/BGLiveTrackingAttributes.swift +52 -0
  116. package/ios/locationpush/BGLocationPushDeliverer.swift +260 -0
  117. package/ios/locationpush/BGLocationPushService.swift +161 -0
  118. package/ios/locationpush/BGLocationPushShared.swift +98 -0
  119. package/ios/locationpush/BGLocationPushSocketClient.swift +198 -0
  120. package/lib/module/NativeBgGeolocation.js +5 -0
  121. package/lib/module/NativeBgGeolocation.js.map +1 -0
  122. package/lib/module/events.js +20 -0
  123. package/lib/module/events.js.map +1 -0
  124. package/lib/module/index.js +706 -0
  125. package/lib/module/index.js.map +1 -0
  126. package/lib/module/package.json +1 -0
  127. package/lib/module/types.js +2 -0
  128. package/lib/module/types.js.map +1 -0
  129. package/lib/typescript/package.json +1 -0
  130. package/lib/typescript/src/NativeBgGeolocation.d.ts +57 -0
  131. package/lib/typescript/src/NativeBgGeolocation.d.ts.map +1 -0
  132. package/lib/typescript/src/events.d.ts +18 -0
  133. package/lib/typescript/src/events.d.ts.map +1 -0
  134. package/lib/typescript/src/index.d.ts +238 -0
  135. package/lib/typescript/src/index.d.ts.map +1 -0
  136. package/lib/typescript/src/types.d.ts +229 -0
  137. package/lib/typescript/src/types.d.ts.map +1 -0
  138. package/package.json +141 -0
  139. package/src/NativeBgGeolocation.ts +236 -0
  140. package/src/events.ts +17 -0
  141. package/src/index.tsx +935 -0
  142. package/src/types.ts +254 -0
@@ -0,0 +1,582 @@
1
+ import Foundation
2
+ import CoreLocation
3
+
4
+ @objc public class BGConfigBuilder: NSObject {
5
+
6
+ @objc public var url: String?
7
+ @objc public var method: String = "POST"
8
+ @objc public var headers: [String: String]?
9
+ @objc public var params: [String: Any]?
10
+ @objc public var authorization: [String: Any]?
11
+ @objc public var httpRootProperty: String = "location"
12
+ @objc public var httpTimeout: Double = 60.0
13
+ @objc public var autoSync: Bool = true
14
+ @objc public var autoSyncThreshold: Int = 0
15
+ @objc public var batchSync: Bool = false
16
+ @objc public var maxBatchSize: Int = -1
17
+ @objc public var disableAutoSyncOnCellular: Bool = false
18
+
19
+ @objc public var desiredAccuracy: Int = 0
20
+ @objc public var distanceFilter: Double = 10.0
21
+ @objc public var stationaryRadius: Double = 25.0
22
+ @objc public var locationTimeout: Double = 60.0
23
+ @objc public var stopTimeout: Double = 5.0
24
+ @objc public var activityType: String = "Other"
25
+ @objc public var pausesLocationUpdatesAutomatically: Bool = false
26
+ @objc public var showsBackgroundLocationIndicator: Bool = false
27
+ @objc public var useSignificantChangesOnly: Bool = false
28
+ @objc public var locationAuthorizationRequest: String = "Always"
29
+ @objc public var locationAuthorizationAlert: [String: Any]?
30
+ @objc public var disableLocationAuthorizationAlert: Bool = false
31
+ @objc public var geofenceProximityRadius: Double = 1000.0
32
+ @objc public var geofenceInitialTriggerEntry: Bool = true
33
+ @objc public var disableElasticity: Bool = false
34
+ @objc public var elasticityMultiplier: Double = 1.0
35
+ @objc public var desiredOdometerAccuracy: Double = 100.0
36
+
37
+ @objc public var stopOnTerminate: Bool = true
38
+ @objc public var startOnBoot: Bool = false
39
+ @objc public var preventSuspend: Bool = false
40
+ @objc public var heartbeatInterval: Double = 60.0
41
+ @objc public var schedule: [String] = []
42
+ @objc public var stopOnStationary: Bool = false
43
+ @objc public var stopAfterElapsedMinutes: Double = 0
44
+ @objc public var stopDetectionDelay: Double = 0
45
+ @objc public var triggerActivities: String = "in_vehicle,on_bicycle,on_foot,running,walking"
46
+
47
+ @objc public var logLevel: Int = 5
48
+ @objc public var logMaxDays: Int = 3
49
+ @objc public var debug: Bool = false
50
+
51
+ @objc public var persistMode: Int = 2
52
+ @objc public var maxDaysToPersist: Int = 1
53
+ @objc public var maxRecordsToPersist: Int = -1
54
+ @objc public var locationsOrderDirection: String = "ASC"
55
+ @objc public var geofenceTemplate: String?
56
+ @objc public var locationTemplate: String?
57
+ @objc public var extras: [String: Any]?
58
+ @objc public var enableTimestampMeta: Bool = false
59
+
60
+ @objc public var isMoving: Bool = false
61
+ @objc public var activityRecognitionInterval: Double = 10000.0
62
+ @objc public var minimumActivityRecognitionConfidence: Int = 75
63
+ @objc public var disableMotionActivityUpdates: Bool = false
64
+ @objc public var disableStopDetection: Bool = false
65
+
66
+ private var dirtyKeys: Set<String> = []
67
+
68
+ @objc public override init() {
69
+ super.init()
70
+ applyDefaults()
71
+ }
72
+
73
+ @objc public func applyDefaults() {
74
+ }
75
+
76
+ @objc public func setDirty(_ key: String) {
77
+ dirtyKeys.insert(key)
78
+ }
79
+
80
+ @objc public func eachDirtyProperty(_ block: (String, Any?) -> Void) {
81
+ for key in dirtyKeys {
82
+ block(key, value(forKey: key, withType: ""))
83
+ }
84
+ }
85
+
86
+ public func value(forKey key: String, withType type: String) -> Any? {
87
+ return nil
88
+ }
89
+
90
+ @objc public func valueForKey(_ key: String, withType type: String) -> Any? {
91
+ return value(forKey: key, withType: type)
92
+ }
93
+
94
+ @objc public class func decodeActivityType(_ type: String) -> CLActivityType {
95
+ return BGGeolocationConfig.activityType(fromString: type) ?? .other
96
+ }
97
+
98
+ @objc public class func decodeDesiredAccuracy(_ accuracy: Any) -> CLLocationAccuracy {
99
+ return BGGeolocationConfig.decodeDesiredAccuracy(accuracy)
100
+ }
101
+
102
+ @objc public class func eachProperty(_ obj: AnyObject, callback: (String, String, Any?) -> Void) {
103
+ }
104
+
105
+ @objc public class func getPropertyType(_ key: String) -> String {
106
+ return "string"
107
+ }
108
+
109
+ @objc public class func value(_ value1: Any?, isEqualTo value2: Any?, withType type: String) -> Bool {
110
+ guard let v1 = value1, let v2 = value2 else { return value1 == nil && value2 == nil }
111
+ if let n1 = v1 as? NSObject, let n2 = v2 as? NSObject { return n1.isEqual(n2) }
112
+ return false
113
+ }
114
+
115
+ @objc public func toDictionary() -> [String: Any] {
116
+ var dict: [String: Any] = [:]
117
+ if let url = url { dict["url"] = url }
118
+ dict["method"] = method
119
+ if let headers = headers { dict["headers"] = headers }
120
+ if let params = params { dict["params"] = params }
121
+ dict["httpRootProperty"] = httpRootProperty
122
+ dict["httpTimeout"] = httpTimeout
123
+ dict["autoSync"] = autoSync
124
+ dict["autoSyncThreshold"] = autoSyncThreshold
125
+ dict["batchSync"] = batchSync
126
+ dict["maxBatchSize"] = maxBatchSize
127
+ dict["desiredAccuracy"] = desiredAccuracy
128
+ dict["distanceFilter"] = distanceFilter
129
+ dict["stationaryRadius"] = stationaryRadius
130
+ dict["locationTimeout"] = locationTimeout
131
+ dict["stopTimeout"] = stopTimeout
132
+ dict["activityType"] = activityType
133
+ dict["pausesLocationUpdatesAutomatically"] = pausesLocationUpdatesAutomatically
134
+ dict["useSignificantChangesOnly"] = useSignificantChangesOnly
135
+ dict["locationAuthorizationRequest"] = locationAuthorizationRequest
136
+ dict["geofenceProximityRadius"] = geofenceProximityRadius
137
+ dict["geofenceInitialTriggerEntry"] = geofenceInitialTriggerEntry
138
+ dict["disableElasticity"] = disableElasticity
139
+ dict["elasticityMultiplier"] = elasticityMultiplier
140
+ dict["stopOnTerminate"] = stopOnTerminate
141
+ dict["startOnBoot"] = startOnBoot
142
+ dict["preventSuspend"] = preventSuspend
143
+ dict["heartbeatInterval"] = heartbeatInterval
144
+ dict["schedule"] = schedule
145
+ dict["logLevel"] = logLevel
146
+ dict["logMaxDays"] = logMaxDays
147
+ dict["debug"] = debug
148
+ dict["persistMode"] = persistMode
149
+ dict["maxDaysToPersist"] = maxDaysToPersist
150
+ dict["maxRecordsToPersist"] = maxRecordsToPersist
151
+ dict["isMoving"] = isMoving
152
+ dict["activityRecognitionInterval"] = activityRecognitionInterval
153
+ dict["disableMotionActivityUpdates"] = disableMotionActivityUpdates
154
+ return dict
155
+ }
156
+
157
+ @objc public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
158
+ }
159
+ }
160
+
161
+ @objc public class BGConfigOLD: NSObject, NSCoding {
162
+
163
+ private static var _sharedInstance: BGConfigOLD?
164
+ private static let instanceLock = NSLock()
165
+ private static let storageKey = "BGLocationManager_config_v2"
166
+
167
+ @objc public class func sharedInstance() -> BGConfigOLD {
168
+ instanceLock.lock()
169
+ defer { instanceLock.unlock() }
170
+ if _sharedInstance == nil {
171
+ _sharedInstance = BGConfigOLD()
172
+ }
173
+ return _sharedInstance!
174
+ }
175
+
176
+ @objc public class func decodeConfig(_ dict: [String: Any]) -> BGConfigOLD {
177
+ let config = BGConfigOLD()
178
+ config.updateWithDictionary(dict)
179
+ return config
180
+ }
181
+
182
+ @objc public class func uptime() -> TimeInterval {
183
+ return ProcessInfo.processInfo.systemUptime
184
+ }
185
+
186
+ @objc public class func userDefaults() -> UserDefaults {
187
+ return UserDefaults.standard
188
+ }
189
+
190
+ @objc public class func classForPropertyName(_ name: String, fromObject obj: AnyObject) -> String {
191
+ return "NSString"
192
+ }
193
+
194
+ @objc public class func setValue(_ value: Any?, forObject obj: AnyObject, forKey key: String, withType type: String) {
195
+ obj.setValue(value, forKey: key)
196
+ }
197
+
198
+ // MARK: - Properties
199
+
200
+ @objc public var url: String?
201
+ @objc public var method: String = "POST"
202
+ @objc public var headers: [String: String]?
203
+ @objc public var params: [String: Any]?
204
+ @objc public var authorization: [String: Any]?
205
+ @objc public var httpRootProperty: String = "location"
206
+ @objc public var httpTimeout: Double = 60.0
207
+ @objc public var autoSync: Bool = true
208
+ @objc public var autoSyncThreshold: Int = 0
209
+ @objc public var batchSync: Bool = false
210
+ @objc public var maxBatchSize: Int = -1
211
+ @objc public var disableAutoSyncOnCellular: Bool = false
212
+
213
+ @objc public var desiredAccuracy: Int = 0
214
+ @objc public var distanceFilter: Double = 10.0
215
+ @objc public var stationaryRadius: Double = 25.0
216
+ @objc public var locationTimeout: Double = 60.0
217
+ @objc public var stopTimeout: Double = 5.0
218
+ @objc public var activityType: String = "Other"
219
+ @objc public var pausesLocationUpdatesAutomatically: Bool = false
220
+ @objc public var showsBackgroundLocationIndicator: Bool = false
221
+ @objc public var useSignificantChangesOnly: Bool = false
222
+ @objc public var locationAuthorizationRequest: String = "Always"
223
+ @objc public var locationAuthorizationAlert: [String: Any]?
224
+ @objc public var disableLocationAuthorizationAlert: Bool = false
225
+ @objc public var geofenceProximityRadius: Double = 1000.0
226
+ @objc public var geofenceInitialTriggerEntry: Bool = true
227
+ @objc public var disableElasticity: Bool = false
228
+ @objc public var elasticityMultiplier: Double = 1.0
229
+ @objc public var desiredOdometerAccuracy: Double = 100.0
230
+
231
+ @objc public var stopOnTerminate: Bool = true
232
+ @objc public var startOnBoot: Bool = false
233
+ @objc public var preventSuspend: Bool = false
234
+ @objc public var heartbeatInterval: Double = 60.0
235
+ @objc public var schedule: [String] = []
236
+ @objc public var stopOnStationary: Bool = false
237
+ @objc public var stopAfterElapsedMinutes: Double = 0
238
+ @objc public var stopDetectionDelay: Double = 0
239
+ @objc public var triggerActivities: String = "in_vehicle,on_bicycle,on_foot,running,walking"
240
+
241
+ @objc public var logLevel: Int = 5
242
+ @objc public var logMaxDays: Int = 3
243
+ @objc public var debug: Bool = false
244
+
245
+ @objc public var persistMode: Int = 2
246
+ @objc public var maxDaysToPersist: Int = 1
247
+ @objc public var maxRecordsToPersist: Int = -1
248
+ @objc public var locationsOrderDirection: String = "ASC"
249
+ @objc public var geofenceTemplate: String?
250
+ @objc public var locationTemplate: String?
251
+ @objc public var extras: [String: Any]?
252
+ @objc public var enableTimestampMeta: Bool = false
253
+
254
+ @objc public var enabled: Bool = false
255
+ @objc public var isMoving: Bool = false
256
+ @objc public var trackingMode: Int = 1
257
+ @objc public var didLaunchInBackground: Bool = false
258
+ @objc public var didRequestUpgradeLocationAuthorization: Bool = false
259
+ @objc public var lastLocationAuthorizationStatus: Int = 0
260
+ @objc public var iOSHasWarnedLocationServicesOff: Bool = false
261
+ @objc public var schedulerEnabled: Bool = false
262
+ @objc public var odometer: Double = 0
263
+
264
+ @objc public var activityRecognitionInterval: Double = 10000.0
265
+ @objc public var minimumActivityRecognitionConfidence: Int = 75
266
+ @objc public var disableMotionActivityUpdates: Bool = false
267
+ @objc public var disableStopDetection: Bool = false
268
+
269
+ private var listeners: [String: [(String, ([String: Any]) -> Void)]] = [:]
270
+ private var dirtyKeys: Set<String> = []
271
+ private var plugins: [String: AnyObject] = [:]
272
+ private let listenersLock = NSLock()
273
+
274
+ @objc public override init() {
275
+ super.init()
276
+ applyDefaults()
277
+ }
278
+
279
+ @objc public required init?(coder: NSCoder) {
280
+ super.init()
281
+ applyDefaults()
282
+ if let dict = coder.decodeObject(forKey: "config") as? [String: Any] {
283
+ applyDictionary(dict)
284
+ }
285
+ enabled = coder.decodeBool(forKey: "enabled")
286
+ isMoving = coder.decodeBool(forKey: "isMoving")
287
+ odometer = coder.decodeDouble(forKey: "odometer")
288
+ }
289
+
290
+ @objc public func encode(with coder: NSCoder) {
291
+ coder.encode(toDictionary(), forKey: "config")
292
+ coder.encode(enabled, forKey: "enabled")
293
+ coder.encode(isMoving, forKey: "isMoving")
294
+ coder.encode(odometer, forKey: "odometer")
295
+ }
296
+
297
+ @objc public func applyDefaults() {
298
+ }
299
+
300
+ // MARK: - Update
301
+
302
+ @objc public func updateWithDictionary(_ dict: [String: Any]) {
303
+ applyDictionary(dict)
304
+ persist()
305
+ ts_emitDirtyChanges()
306
+ }
307
+
308
+ @objc public func updateWithBlock(_ block: (BGConfigBuilder) -> Void) {
309
+ let builder = BGConfigBuilder()
310
+ block(builder)
311
+ updateWithDictionary(builder.toDictionary())
312
+ }
313
+
314
+ private func applyDictionary(_ dict: [String: Any]) {
315
+ if let v = dict["url"] as? String { url = v }
316
+ if let v = dict["method"] as? String { method = v }
317
+ if let v = dict["headers"] as? [String: String] { headers = v }
318
+ if let v = dict["params"] as? [String: Any] { params = v }
319
+ if let v = dict["httpRootProperty"] as? String { httpRootProperty = v }
320
+ if let v = dict["httpTimeout"] as? Double { httpTimeout = v }
321
+ if let v = dict["autoSync"] as? Bool { autoSync = v }
322
+ if let v = dict["autoSyncThreshold"] as? Int { autoSyncThreshold = v }
323
+ if let v = dict["batchSync"] as? Bool { batchSync = v }
324
+ if let v = dict["maxBatchSize"] as? Int { maxBatchSize = v }
325
+ if let v = dict["desiredAccuracy"] as? Int { desiredAccuracy = v }
326
+ if let v = dict["distanceFilter"] as? Double { distanceFilter = v }
327
+ if let v = dict["stationaryRadius"] as? Double { stationaryRadius = v }
328
+ if let v = dict["locationTimeout"] as? Double { locationTimeout = v }
329
+ if let v = dict["stopTimeout"] as? Double { stopTimeout = v }
330
+ if let v = dict["activityType"] as? String { activityType = v }
331
+ if let v = dict["pausesLocationUpdatesAutomatically"] as? Bool { pausesLocationUpdatesAutomatically = v }
332
+ if let v = dict["showsBackgroundLocationIndicator"] as? Bool { showsBackgroundLocationIndicator = v }
333
+ if let v = dict["useSignificantChangesOnly"] as? Bool { useSignificantChangesOnly = v }
334
+ if let v = dict["locationAuthorizationRequest"] as? String { locationAuthorizationRequest = v }
335
+ if let v = dict["geofenceProximityRadius"] as? Double { geofenceProximityRadius = v }
336
+ if let v = dict["geofenceInitialTriggerEntry"] as? Bool { geofenceInitialTriggerEntry = v }
337
+ if let v = dict["disableElasticity"] as? Bool { disableElasticity = v }
338
+ if let v = dict["elasticityMultiplier"] as? Double { elasticityMultiplier = v }
339
+ if let v = dict["stopOnTerminate"] as? Bool { stopOnTerminate = v }
340
+ if let v = dict["startOnBoot"] as? Bool { startOnBoot = v }
341
+ if let v = dict["preventSuspend"] as? Bool { preventSuspend = v }
342
+ if let v = dict["heartbeatInterval"] as? Double { heartbeatInterval = v }
343
+ if let v = dict["schedule"] as? [String] { schedule = v }
344
+ if let v = dict["logLevel"] as? Int { logLevel = v }
345
+ if let v = dict["logMaxDays"] as? Int { logMaxDays = v }
346
+ if let v = dict["debug"] as? Bool { debug = v }
347
+ if let v = dict["persistMode"] as? Int { persistMode = v }
348
+ if let v = dict["maxDaysToPersist"] as? Int { maxDaysToPersist = v }
349
+ if let v = dict["maxRecordsToPersist"] as? Int { maxRecordsToPersist = v }
350
+ if let v = dict["locationsOrderDirection"] as? String { locationsOrderDirection = v }
351
+ if let v = dict["extras"] as? [String: Any] { extras = v }
352
+ if let v = dict["enableTimestampMeta"] as? Bool { enableTimestampMeta = v }
353
+ if let v = dict["enabled"] as? Bool { enabled = v }
354
+ if let v = dict["isMoving"] as? Bool { isMoving = v }
355
+ if let v = dict["odometer"] as? Double { odometer = v }
356
+ if let v = dict["activityRecognitionInterval"] as? Double { activityRecognitionInterval = v }
357
+ if let v = dict["disableMotionActivityUpdates"] as? Bool { disableMotionActivityUpdates = v }
358
+ if let v = dict["authorization"] as? [String: Any] { authorization = v }
359
+ if let v = dict["geofenceTemplate"] as? String { geofenceTemplate = v }
360
+ if let v = dict["locationTemplate"] as? String { locationTemplate = v }
361
+ if let v = dict["triggerActivities"] as? String { triggerActivities = v }
362
+ if let v = dict["stopAfterElapsedMinutes"] as? Double { stopAfterElapsedMinutes = v }
363
+ if let v = dict["stopDetectionDelay"] as? Double { stopDetectionDelay = v }
364
+ }
365
+
366
+ // MARK: - Persistence
367
+
368
+ @objc public func persist() {
369
+ let data = try? NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: false)
370
+ UserDefaults.standard.set(data, forKey: BGConfigOLD.storageKey)
371
+ UserDefaults.standard.synchronize()
372
+ }
373
+
374
+ // MARK: - Serialization
375
+
376
+ @objc public func toDictionary() -> [String: Any] {
377
+ return toDictionary(false)
378
+ }
379
+
380
+ @objc public func toDictionary(_ includeState: Bool) -> [String: Any] {
381
+ var dict: [String: Any] = [:]
382
+ if let url = url { dict["url"] = url }
383
+ dict["method"] = method
384
+ if let headers = headers { dict["headers"] = headers }
385
+ dict["httpRootProperty"] = httpRootProperty
386
+ dict["httpTimeout"] = httpTimeout
387
+ dict["autoSync"] = autoSync
388
+ dict["autoSyncThreshold"] = autoSyncThreshold
389
+ dict["batchSync"] = batchSync
390
+ dict["maxBatchSize"] = maxBatchSize
391
+ dict["desiredAccuracy"] = desiredAccuracy
392
+ dict["distanceFilter"] = distanceFilter
393
+ dict["stationaryRadius"] = stationaryRadius
394
+ dict["locationTimeout"] = locationTimeout
395
+ dict["stopTimeout"] = stopTimeout
396
+ dict["activityType"] = activityType
397
+ dict["pausesLocationUpdatesAutomatically"] = pausesLocationUpdatesAutomatically
398
+ dict["showsBackgroundLocationIndicator"] = showsBackgroundLocationIndicator
399
+ dict["useSignificantChangesOnly"] = useSignificantChangesOnly
400
+ dict["locationAuthorizationRequest"] = locationAuthorizationRequest
401
+ dict["geofenceProximityRadius"] = geofenceProximityRadius
402
+ dict["geofenceInitialTriggerEntry"] = geofenceInitialTriggerEntry
403
+ dict["disableElasticity"] = disableElasticity
404
+ dict["elasticityMultiplier"] = elasticityMultiplier
405
+ dict["stopOnTerminate"] = stopOnTerminate
406
+ dict["startOnBoot"] = startOnBoot
407
+ dict["preventSuspend"] = preventSuspend
408
+ dict["heartbeatInterval"] = heartbeatInterval
409
+ dict["schedule"] = schedule
410
+ dict["logLevel"] = logLevel
411
+ dict["logMaxDays"] = logMaxDays
412
+ dict["debug"] = debug
413
+ dict["persistMode"] = persistMode
414
+ dict["maxDaysToPersist"] = maxDaysToPersist
415
+ dict["maxRecordsToPersist"] = maxRecordsToPersist
416
+ dict["locationsOrderDirection"] = locationsOrderDirection
417
+ dict["enableTimestampMeta"] = enableTimestampMeta
418
+ dict["isMoving"] = isMoving
419
+ dict["enabled"] = enabled
420
+ dict["odometer"] = odometer
421
+ dict["activityRecognitionInterval"] = activityRecognitionInterval
422
+ dict["disableMotionActivityUpdates"] = disableMotionActivityUpdates
423
+ dict["triggerActivities"] = triggerActivities
424
+ dict["stopAfterElapsedMinutes"] = stopAfterElapsedMinutes
425
+ dict["stopDetectionDelay"] = stopDetectionDelay
426
+ if let extras = extras { dict["extras"] = extras }
427
+ if let geofenceTemplate = geofenceTemplate { dict["geofenceTemplate"] = geofenceTemplate }
428
+ if let locationTemplate = locationTemplate { dict["locationTemplate"] = locationTemplate }
429
+ if let authorization = authorization { dict["authorization"] = authorization }
430
+ return dict
431
+ }
432
+
433
+ @objc public func toJson() -> String? {
434
+ guard let data = try? JSONSerialization.data(withJSONObject: toDictionary()) else { return nil }
435
+ return String(data: data, encoding: .utf8)
436
+ }
437
+
438
+ // MARK: - Listeners
439
+
440
+ @objc public func onChange(_ keyPath: String, callback: @escaping ([String: Any]) -> Void) {
441
+ listenersLock.lock()
442
+ defer { listenersLock.unlock() }
443
+ if listeners[keyPath] == nil { listeners[keyPath] = [] }
444
+ let token = UUID().uuidString
445
+ listeners[keyPath]!.append((token, callback))
446
+ }
447
+
448
+ @objc public func removeListeners(forKeyPath keyPath: String) {
449
+ listenersLock.lock()
450
+ defer { listenersLock.unlock() }
451
+ listeners.removeValue(forKey: keyPath)
452
+ }
453
+
454
+ @objc public func removeListeners() {
455
+ listenersLock.lock()
456
+ defer { listenersLock.unlock() }
457
+ listeners.removeAll()
458
+ }
459
+
460
+ @objc public func fireOnChange(_ keyPath: String, value: Any?) {
461
+ listenersLock.lock()
462
+ let list = listeners[keyPath] ?? []
463
+ listenersLock.unlock()
464
+ let payload: [String: Any] = ["value": value ?? NSNull()]
465
+ for (_, cb) in list { cb(payload) }
466
+ }
467
+
468
+ // MARK: - Dirty tracking
469
+
470
+ @objc public func ts_addDirty(_ key: String) {
471
+ dirtyKeys.insert(key)
472
+ }
473
+
474
+ @objc public func ts_drainDirty() {
475
+ dirtyKeys.removeAll()
476
+ }
477
+
478
+ private func ts_emitDirtyChanges() {
479
+ let dirty = dirtyKeys
480
+ ts_drainDirty()
481
+ for key in dirty {
482
+ fireOnChange(key, value: value(forKey: key))
483
+ }
484
+ }
485
+
486
+ // MARK: - Computed properties
487
+
488
+ @objc public func hasSchedule() -> Bool {
489
+ return !schedule.isEmpty
490
+ }
491
+
492
+ @objc public func hasTriggerActivities() -> Bool {
493
+ return !triggerActivities.isEmpty
494
+ }
495
+
496
+ @objc public func hasTriggerActivity(_ activity: String) -> Bool {
497
+ return triggerActivities.contains(activity)
498
+ }
499
+
500
+ @objc public func hasValidUrl() -> Bool {
501
+ guard let url = url, !url.isEmpty else { return false }
502
+ return URL(string: url) != nil
503
+ }
504
+
505
+ @objc public func hasPluginForEvent(_ event: String) -> Bool {
506
+ return plugins[event] != nil
507
+ }
508
+
509
+ @objc public func isLocationTrackingMode() -> Bool {
510
+ return trackingMode == 1
511
+ }
512
+
513
+ @objc public func isFirstBoot() -> Bool {
514
+ return !UserDefaults.standard.bool(forKey: "BGLocationManager_booted")
515
+ }
516
+
517
+ @objc public func didDeviceReboot() -> Bool {
518
+ let stored = UserDefaults.standard.double(forKey: "BGLocationManager_uptime")
519
+ return stored > ProcessInfo.processInfo.systemUptime
520
+ }
521
+
522
+ @objc public func getPausesLocationUpdates() -> Bool {
523
+ return pausesLocationUpdatesAutomatically
524
+ }
525
+
526
+ @objc public func shouldPersist(_ location: BGLocation) -> Bool {
527
+ return persistMode > 0
528
+ }
529
+
530
+ @objc public func getLocationAuthorizationAlertStrings() -> [String: Any] {
531
+ return locationAuthorizationAlert ?? [
532
+ "title": "Background Location Access",
533
+ "message": "This app requires location access.",
534
+ "cancel": "Cancel",
535
+ "settings": "Settings"
536
+ ]
537
+ }
538
+
539
+ @objc public func incrementOdometer(_ distance: Double) {
540
+ odometer += distance
541
+ }
542
+
543
+ // MARK: - Plugins
544
+
545
+ @objc public func registerPlugin(_ plugin: AnyObject) {
546
+ plugins[NSStringFromClass(type(of: plugin))] = plugin
547
+ }
548
+
549
+ // MARK: - Module event observation
550
+
551
+ @objc public func ts_observeStateProperties() {
552
+ }
553
+
554
+ @objc public func ts_getStateProperties() -> [String] {
555
+ return []
556
+ }
557
+
558
+ @objc public func ts_registerModulesForEventRegistry() {
559
+ }
560
+
561
+ @objc public func ts_emitModuleLeafDiffs(forProperty property: String, oldModule: AnyObject?, newModule: AnyObject?) {
562
+ }
563
+
564
+ // MARK: - Reset
565
+
566
+ @objc public func reset() {
567
+ reset([:])
568
+ }
569
+
570
+ @objc public func reset(_ dict: [String: Any]) {
571
+ applyDefaults()
572
+ if !dict.isEmpty { applyDictionary(dict) }
573
+ persist()
574
+ }
575
+
576
+ // MARK: - KVO
577
+
578
+ @objc public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
579
+ guard let keyPath = keyPath else { return }
580
+ fireOnChange(keyPath, value: change?[.newKey])
581
+ }
582
+ }
@@ -0,0 +1,15 @@
1
+ import Foundation
2
+
3
+ @objc public final class BGConnectivityChangeEvent: NSObject {
4
+
5
+ @objc public private(set) var hasConnection: Bool
6
+
7
+ @objc public init(hasConnection: Bool) {
8
+ self.hasConnection = hasConnection
9
+ super.init()
10
+ }
11
+
12
+ @objc public func toDictionary() -> [String: Any] {
13
+ return ["connected": hasConnection]
14
+ }
15
+ }