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,48 @@
1
+ import Foundation
2
+
3
+ @objc public final class AtomicBoolean: NSObject {
4
+
5
+ private var _value: Bool = false
6
+ private var _lock = os_unfair_lock_s()
7
+
8
+ @objc public override init() {
9
+ super.init()
10
+ setValue(false)
11
+ }
12
+
13
+ @objc public init(value: Bool) {
14
+ super.init()
15
+ _value = value
16
+ }
17
+
18
+ @objc public func getValue() -> Bool {
19
+ os_unfair_lock_lock(&_lock)
20
+ let v = _value
21
+ os_unfair_lock_unlock(&_lock)
22
+ return v
23
+ }
24
+
25
+ @objc public func setValue(_ value: Bool) {
26
+ os_unfair_lock_lock(&_lock)
27
+ _value = value
28
+ os_unfair_lock_unlock(&_lock)
29
+ }
30
+
31
+ @objc public func compareTo(_ expected: Bool, andSetValue newValue: Bool) -> Bool {
32
+ os_unfair_lock_lock(&_lock)
33
+ defer { os_unfair_lock_unlock(&_lock) }
34
+ if _value == expected {
35
+ _value = newValue
36
+ return true
37
+ }
38
+ return false
39
+ }
40
+
41
+ @objc public func getAndSetValue(_ newValue: Bool) -> Bool {
42
+ os_unfair_lock_lock(&_lock)
43
+ let old = _value
44
+ _value = newValue
45
+ os_unfair_lock_unlock(&_lock)
46
+ return old
47
+ }
48
+ }
@@ -0,0 +1,20 @@
1
+ import Foundation
2
+
3
+ @objc public final class BGActivityChangeEvent: NSObject {
4
+
5
+ @objc public private(set) var confidence: Int
6
+ @objc public private(set) var activity: String
7
+
8
+ @objc public init(activityName: String?, confidence: Int) {
9
+ self.confidence = confidence
10
+ self.activity = activityName ?? "unknown"
11
+ super.init()
12
+ }
13
+
14
+ @objc public func toDictionary() -> [String: Any] {
15
+ return [
16
+ "activity": activity,
17
+ "confidence": confidence
18
+ ]
19
+ }
20
+ }
@@ -0,0 +1,71 @@
1
+ import Foundation
2
+
3
+ @objc public final class BGActivityConfig: BGConfigModuleBase {
4
+
5
+ @objc public var disableMotionActivityUpdates: Bool = false
6
+ @objc public var disableStopDetection: Bool = false
7
+ @objc public var stopOnStationary: Bool = false
8
+ @objc public var stopDetectionDelay: Double = 0
9
+ @objc public var activityRecognitionInterval: Double = 0
10
+ @objc public var minimumActivityRecognitionConfidence: Int = 0
11
+ @objc public var triggerActivities: String = ""
12
+
13
+ @objc public override func applyDefaults() {
14
+ stopDetectionDelay = 0
15
+ activityRecognitionInterval = 10000.0
16
+ minimumActivityRecognitionConfidence = 70
17
+ disableMotionActivityUpdates = false
18
+ disableStopDetection = false
19
+ stopOnStationary = false
20
+ triggerActivities = ""
21
+ }
22
+
23
+ @objc public override func propertySpecs() -> [BGPropertySpecImpl] {
24
+ return [
25
+ BGPropertySpecImpl(name: "stopDetectionDelay", type: "integer"),
26
+ BGPropertySpecImpl(name: "activityRecognitionInterval", type: "integer"),
27
+ BGPropertySpecImpl(name: "minimumActivityRecognitionConfidence", type: "integer"),
28
+ BGPropertySpecImpl(name: "disableMotionActivityUpdates", type: "bool"),
29
+ BGPropertySpecImpl(name: "disableStopDetection", type: "bool"),
30
+ BGPropertySpecImpl(name: "stopOnStationary", type: "bool"),
31
+ BGPropertySpecImpl(name: "triggerActivities", type: "string")
32
+ ]
33
+ }
34
+
35
+ @objc public override func contributeDeprecatedProperties(_ dict: NSMutableDictionary, redact: Bool) {
36
+ dict.setObject(NSNumber(value: stopDetectionDelay), forKey: "stopDetectionDelay" as NSString)
37
+ dict.setObject(NSNumber(value: activityRecognitionInterval), forKey: "activityRecognitionInterval" as NSString)
38
+ dict.setObject(NSNumber(value: minimumActivityRecognitionConfidence), forKey: "minimumActivityRecognitionConfidence" as NSString)
39
+ dict.setObject(NSNumber(value: disableMotionActivityUpdates), forKey: "disableMotionActivityUpdates" as NSString)
40
+ dict.setObject(NSNumber(value: disableStopDetection), forKey: "disableStopDetection" as NSString)
41
+ dict.setObject(NSNumber(value: stopOnStationary), forKey: "stopOnStationary" as NSString)
42
+ dict.setObject(triggerActivities, forKey: "triggerActivities" as NSString)
43
+ }
44
+
45
+ @objc public override func validateConfiguration() -> Bool {
46
+ if disableStopDetection && stopOnStationary {
47
+ let logger = BGLog.sharedInstance()
48
+ if logger.shouldLog(2) {
49
+ let message = "BGActivityConfig: stopOnStationary is enabled but disableStopDetection is also enabled - stopOnStationary will have no effect"
50
+ logger.log(2, tag: 9, function: "-[BGActivityConfig validateConfiguration]", message: message)
51
+ }
52
+ }
53
+ if disableMotionActivityUpdates && !disableStopDetection {
54
+ let logger = BGLog.sharedInstance()
55
+ if logger.shouldLog(2) {
56
+ let message = "BGActivityConfig: Motion activity updates are disabled but stop detection is enabled - stop detection may not work properly"
57
+ logger.log(2, tag: 9, function: "-[BGActivityConfig validateConfiguration]", message: message)
58
+ }
59
+ }
60
+ return true
61
+ }
62
+
63
+ public override var description: String {
64
+ return String(format: "<%@: %p> {\n stopDetectionDelay: %.0fs\n activityRecognitionInterval: %.0f ms\n minimumActivityRecognitionConfidence: %ld%%\n disableMotionActivityUpdates: %@\n disableStopDetection: %@\n stopOnStationary: %@\n}",
65
+ String(describing: type(of: self)), self,
66
+ stopDetectionDelay, activityRecognitionInterval, minimumActivityRecognitionConfidence,
67
+ disableMotionActivityUpdates ? "YES" : "NO",
68
+ disableStopDetection ? "YES" : "NO",
69
+ stopOnStationary ? "YES" : "NO")
70
+ }
71
+ }
@@ -0,0 +1,92 @@
1
+ import Foundation
2
+
3
+ @objc public class BGAppConfig: BGConfigModuleBase {
4
+
5
+ @objc public var stopOnTerminate: Bool = true
6
+ @objc public var startOnBoot: Bool = false
7
+ @objc public var preventSuspend: Bool = false
8
+ @objc public var heartbeatInterval: Double = 60.0
9
+ @objc public var schedule: [String] = []
10
+ @objc public var liveActivityEnabled: Bool = false
11
+ @objc public var liveActivityTitle: String = "Live location"
12
+ @objc public var liveActivitySubtitle: String = "Background tracking is active"
13
+ @objc public var liveActivityUpdateInterval: Double = 15.0
14
+ @objc public var liveActivityStaleSeconds: Double = 120.0
15
+ @objc public var liveActivityPushUpdates: Bool = false
16
+ @objc public var locationPushEnabled: Bool = false
17
+ @objc public var trackingAudioEnabled: Bool = false
18
+ @objc public var trackingAudioVolume: Double = 0.04
19
+ @objc public var trackingAudioMixWithOthers: Bool = true
20
+
21
+ @objc public override func applyDefaults() {
22
+ stopOnTerminate = true
23
+ startOnBoot = false
24
+ preventSuspend = false
25
+ heartbeatInterval = 60.0
26
+ schedule = []
27
+ liveActivityEnabled = false
28
+ liveActivityTitle = "Live location"
29
+ liveActivitySubtitle = "Background tracking is active"
30
+ liveActivityUpdateInterval = 15.0
31
+ liveActivityStaleSeconds = 120.0
32
+ liveActivityPushUpdates = false
33
+ locationPushEnabled = false
34
+ trackingAudioEnabled = false
35
+ trackingAudioVolume = 0.04
36
+ trackingAudioMixWithOthers = true
37
+ }
38
+
39
+ @objc public var hasSchedule: Bool {
40
+ return !schedule.isEmpty
41
+ }
42
+
43
+ @objc public var isBackgroundExecutionEnabled: Bool {
44
+ return !stopOnTerminate || startOnBoot || preventSuspend
45
+ }
46
+
47
+ @objc public override func propertySpecs() -> [BGPropertySpecImpl] {
48
+ return [
49
+ BGPropertySpec(name: "stopOnTerminate", type: "bool"),
50
+ BGPropertySpec(name: "startOnBoot", type: "bool"),
51
+ BGPropertySpec(name: "preventSuspend", type: "bool"),
52
+ BGPropertySpec(name: "heartbeatInterval", type: "double"),
53
+ BGPropertySpec(name: "schedule", type: "array"),
54
+ BGPropertySpec(name: "liveActivityEnabled", type: "bool"),
55
+ BGPropertySpec(name: "liveActivityTitle", type: "string"),
56
+ BGPropertySpec(name: "liveActivitySubtitle", type: "string"),
57
+ BGPropertySpec(name: "liveActivityUpdateInterval", type: "double"),
58
+ BGPropertySpec(name: "liveActivityStaleSeconds", type: "double"),
59
+ BGPropertySpec(name: "liveActivityPushUpdates", type: "bool"),
60
+ BGPropertySpec(name: "locationPushEnabled", type: "bool"),
61
+ BGPropertySpec(name: "trackingAudioEnabled", type: "bool"),
62
+ BGPropertySpec(name: "trackingAudioVolume", type: "double"),
63
+ BGPropertySpec(name: "trackingAudioMixWithOthers", type: "bool")
64
+ ]
65
+ }
66
+
67
+ @objc public override func contributeDeprecatedProperties(_ dict: NSMutableDictionary, redact: Bool) {
68
+ dict["stopOnTerminate"] = stopOnTerminate
69
+ dict["startOnBoot"] = startOnBoot
70
+ dict["preventSuspend"] = preventSuspend
71
+ dict["heartbeatInterval"] = heartbeatInterval
72
+ dict["schedule"] = schedule
73
+ dict["liveActivityEnabled"] = liveActivityEnabled
74
+ dict["liveActivityTitle"] = liveActivityTitle
75
+ dict["liveActivitySubtitle"] = liveActivitySubtitle
76
+ dict["liveActivityUpdateInterval"] = liveActivityUpdateInterval
77
+ dict["liveActivityStaleSeconds"] = liveActivityStaleSeconds
78
+ dict["liveActivityPushUpdates"] = liveActivityPushUpdates
79
+ dict["locationPushEnabled"] = locationPushEnabled
80
+ dict["trackingAudioEnabled"] = trackingAudioEnabled
81
+ dict["trackingAudioVolume"] = trackingAudioVolume
82
+ dict["trackingAudioMixWithOthers"] = trackingAudioMixWithOthers
83
+ }
84
+
85
+ @objc public override func validateConfiguration() -> Bool {
86
+ return true
87
+ }
88
+
89
+ @objc public override var description: String {
90
+ return "<BGAppConfig stopOnTerminate=\(stopOnTerminate) startOnBoot=\(startOnBoot) preventSuspend=\(preventSuspend) heartbeatInterval=\(heartbeatInterval)>"
91
+ }
92
+ }
@@ -0,0 +1,147 @@
1
+ import Foundation
2
+ import UIKit
3
+ import CoreLocation
4
+
5
+ @objc public class BGAppState: NSObject {
6
+
7
+ private static var _sharedInstance: BGAppState?
8
+ private static let onceLock = NSLock()
9
+
10
+ @objc public var isInBackground: Bool = false
11
+ @objc public var clientReady: Bool = false
12
+ @objc public var didLaunchInBackground: Bool = false
13
+ @objc public var foregroundObserved: Bool = false
14
+ @objc public var flippedToUserInitiated: Bool = false
15
+ @objc public var heuristicResult: String?
16
+ @objc public var heuristicTimerFired: Bool = false
17
+ @objc public var launchClassificationFinalized: Bool = false
18
+ @objc public var resolvingRoot: Bool = false
19
+ @objc public var readyCallbackDelivered: Bool = false
20
+ @objc public var launchTimestamp: Date?
21
+ @objc public var heuristicTimer: Timer?
22
+ @objc public var rootViewController: UIViewController?
23
+ @objc public var readyCallback: (([String: Any]) -> Void)?
24
+ @objc public var pendingRootCallbacks: [[String: Any]] = []
25
+
26
+ @objc public class func sharedInstance() -> BGAppState {
27
+ onceLock.lock()
28
+ defer { onceLock.unlock() }
29
+ if _sharedInstance == nil {
30
+ _sharedInstance = BGAppState()
31
+ }
32
+ return _sharedInstance!
33
+ }
34
+
35
+ @objc public override init() {
36
+ super.init()
37
+ launchTimestamp = Date()
38
+ isInBackground = UIApplication.shared.applicationState == .background
39
+ didLaunchInBackground = isInBackground || UserDefaults.standard.bool(forKey: "BGLocationManager_didLaunchInBackground")
40
+ setupNotifications()
41
+ }
42
+
43
+ deinit {
44
+ NotificationCenter.default.removeObserver(self)
45
+ cancelHeuristicTimer()
46
+ }
47
+
48
+ private func setupNotifications() {
49
+ NotificationCenter.default.addObserver(self, selector: #selector(onDidBecomeActive),
50
+ name: UIApplication.didBecomeActiveNotification, object: nil)
51
+ NotificationCenter.default.addObserver(self, selector: #selector(onEnterBackground),
52
+ name: UIApplication.didEnterBackgroundNotification, object: nil)
53
+ NotificationCenter.default.addObserver(self, selector: #selector(onEnterForeground),
54
+ name: UIApplication.willEnterForegroundNotification, object: nil)
55
+ NotificationCenter.default.addObserver(self, selector: #selector(onWillTerminate),
56
+ name: UIApplication.willTerminateNotification, object: nil)
57
+ }
58
+
59
+ @objc public func onDidBecomeActive() {
60
+ isInBackground = false
61
+ foregroundObserved = true
62
+ BGTrackingService.sharedInstance().onResume()
63
+ }
64
+
65
+ @objc public func onEnterBackground() {
66
+ isInBackground = true
67
+ startHeuristicTimerIfNeeded()
68
+ BGTrackingService.sharedInstance().onSuspend()
69
+ }
70
+
71
+ @objc public func onEnterForeground() {
72
+ isInBackground = false
73
+ cancelHeuristicTimer()
74
+ }
75
+
76
+ @objc public func onWillTerminate() {
77
+ BGTrackingService.sharedInstance().onAppTerminate()
78
+ }
79
+
80
+ @objc public func startHeuristicTimerIfNeeded() {
81
+ guard heuristicTimer == nil else { return }
82
+ heuristicTimer = Timer.scheduledTimer(timeInterval: 0.8,
83
+ target: self,
84
+ selector: #selector(heuristicTimerFiredAction),
85
+ userInfo: nil,
86
+ repeats: false)
87
+ }
88
+
89
+ @objc private func heuristicTimerFiredAction() {
90
+ heuristicTimerFired = true
91
+ heuristicTimer = nil
92
+ }
93
+
94
+ @objc public func cancelHeuristicTimer() {
95
+ heuristicTimer?.invalidate()
96
+ heuristicTimer = nil
97
+ }
98
+
99
+ @objc public func ready(_ callback: @escaping ([String: Any]) -> Void) {
100
+ readyCallback = callback
101
+ if readyCallbackDelivered {
102
+ callback([:])
103
+ }
104
+ }
105
+
106
+ @objc public func hasBackgroundLocationMode() -> Bool {
107
+ guard let modes = Bundle.main.object(forInfoDictionaryKey: "UIBackgroundModes") as? [String] else {
108
+ return false
109
+ }
110
+ return modes.contains("location")
111
+ }
112
+
113
+ @objc public func hasAnyLocationUsageDescription() -> Bool {
114
+ let keys = ["NSLocationAlwaysUsageDescription",
115
+ "NSLocationWhenInUseUsageDescription",
116
+ "NSLocationAlwaysAndWhenInUseUsageDescription"]
117
+ return keys.contains { Bundle.main.object(forInfoDictionaryKey: $0) != nil }
118
+ }
119
+
120
+ @objc public func canShowBackgroundLocationIndicator() -> Bool {
121
+ if #available(iOS 13.0, *) {
122
+ return true
123
+ }
124
+ return false
125
+ }
126
+
127
+ @objc public func applySafeBackgroundLocationSettings(toManager manager: CLLocationManager,
128
+ showsIndicator: Bool) {
129
+ if #available(iOS 11.0, *) {
130
+ manager.showsBackgroundLocationIndicator = showsIndicator
131
+ }
132
+ }
133
+
134
+ @objc public func getRootViewController(_ completion: @escaping (UIViewController?) -> Void) {
135
+ DispatchQueue.main.async {
136
+ completion(self.topPresenter())
137
+ }
138
+ }
139
+
140
+ @objc public func topPresenter() -> UIViewController? {
141
+ var top = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.rootViewController
142
+ while let presented = top?.presentedViewController {
143
+ top = presented
144
+ }
145
+ return top
146
+ }
147
+ }
@@ -0,0 +1,85 @@
1
+ import Foundation
2
+
3
+ @objc public class BGAuthorization: NSObject {
4
+
5
+ @objc public var strategy: String = "JWT"
6
+ @objc public var accessToken: String?
7
+ @objc public var refreshToken: String?
8
+ @objc public var refreshUrl: String?
9
+ @objc public var refreshHeaders: [String: String] = [:]
10
+ @objc public var refreshPayload: [String: Any] = [:]
11
+ @objc public var expires: Date?
12
+
13
+ @objc public var accessRE: String?
14
+ @objc public var accessTokenRE: String?
15
+ @objc public var refreshTokenRE: String?
16
+ @objc public var refreshRenewRE: String?
17
+ @objc public var expiresRE: String?
18
+
19
+ @objc public var config: BGAuthorizationConfig?
20
+
21
+ @objc public override init() {
22
+ super.init()
23
+ }
24
+
25
+ @objc public func applyResponseData(_ data: [String: Any]) {
26
+ if let token = resolveValue(data, pattern: accessTokenRE) ?? data["access_token"] as? String {
27
+ accessToken = token
28
+ }
29
+ if let refresh = resolveValue(data, pattern: refreshTokenRE) ?? data["refresh_token"] as? String {
30
+ refreshToken = refresh
31
+ }
32
+ if let expiry = resolveValue(data, pattern: expiresRE) ?? data["expires_at"] as? String {
33
+ let formatter = ISO8601DateFormatter()
34
+ expires = formatter.date(from: expiry)
35
+ }
36
+ }
37
+
38
+ private func resolveValue(_ data: [String: Any], pattern: String?) -> String? {
39
+ guard let pattern = pattern, !pattern.isEmpty else { return nil }
40
+ return data[pattern] as? String
41
+ }
42
+
43
+ public func refreshAuthorization(_ headers: inout [String: String], statusCode: Int) -> Bool {
44
+ guard statusCode == 401, let refreshUrl = refreshUrl, !refreshUrl.isEmpty else { return false }
45
+ return true
46
+ }
47
+
48
+ @objc public func resolve(
49
+ _ request: URLRequest,
50
+ success: @escaping (_ request: URLRequest) -> Void,
51
+ failure: @escaping (_ error: Error) -> Void
52
+ ) {
53
+ var req = request
54
+ if let token = accessToken {
55
+ req.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
56
+ }
57
+ success(req)
58
+ }
59
+
60
+ @objc public func toDictionary() -> [String: Any] {
61
+ return toDictionary(false)
62
+ }
63
+
64
+ @objc public func toDictionary(_ redact: Bool) -> [String: Any] {
65
+ var dict: [String: Any] = ["strategy": strategy]
66
+ if redact {
67
+ dict["accessToken"] = "**redacted**"
68
+ dict["refreshToken"] = "**redacted**"
69
+ } else {
70
+ if let t = accessToken { dict["accessToken"] = t }
71
+ if let t = refreshToken { dict["refreshToken"] = t }
72
+ }
73
+ if let u = refreshUrl { dict["refreshUrl"] = u }
74
+ if let e = expires { dict["expires"] = e.timeIntervalSince1970 }
75
+ return dict
76
+ }
77
+
78
+ @objc public func toString() -> String {
79
+ return "<BGAuthorization strategy=\(strategy)>"
80
+ }
81
+
82
+ @objc public override var description: String {
83
+ return toString()
84
+ }
85
+ }
@@ -0,0 +1,39 @@
1
+ import Foundation
2
+ import UIKit
3
+
4
+ @objc public class BGAuthorizationAlertPresenter: NSObject {
5
+
6
+ @objc public var authorization: BGAuthorization?
7
+ @objc public var alertController: UIAlertController?
8
+
9
+ @objc public init(authorization: BGAuthorization) {
10
+ self.authorization = authorization
11
+ super.init()
12
+ }
13
+
14
+ @objc public var isAlertVisible: Bool {
15
+ return alertController != nil && alertController?.view.window != nil
16
+ }
17
+
18
+ @objc public func getAlertController(withCancelHandler handler: (() -> Void)?) -> UIAlertController {
19
+ let alert = UIAlertController(
20
+ title: "Location Authorization",
21
+ message: "This app requires location access. Please enable it in Settings.",
22
+ preferredStyle: .alert
23
+ )
24
+ alert.addAction(UIAlertAction(title: "Settings", style: .default) { _ in
25
+ if let url = URL(string: UIApplication.openSettingsURLString) {
26
+ UIApplication.shared.open(url)
27
+ }
28
+ })
29
+ alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
30
+ handler?()
31
+ })
32
+ return alert
33
+ }
34
+
35
+ @objc public func dismissAlert() {
36
+ alertController?.dismiss(animated: true)
37
+ alertController = nil
38
+ }
39
+ }
@@ -0,0 +1,50 @@
1
+ import Foundation
2
+
3
+ @objc public class BGAuthorizationConfig: BGConfigModuleBase {
4
+
5
+ @objc public var strategy: String = "JWT"
6
+ @objc public var accessToken: String?
7
+ @objc public var refreshToken: String?
8
+ @objc public var refreshUrl: String?
9
+ @objc public var refreshHeaders: [String: String] = [:]
10
+ @objc public var refreshPayload: [String: Any] = [:]
11
+ @objc public var expires: Date?
12
+
13
+ @objc public override func applyDefaults() {
14
+ strategy = "JWT"
15
+ accessToken = nil
16
+ refreshToken = nil
17
+ refreshUrl = nil
18
+ refreshHeaders = [:]
19
+ refreshPayload = [:]
20
+ expires = nil
21
+ }
22
+
23
+ @objc public func moduleKey() -> String {
24
+ return "authorization"
25
+ }
26
+
27
+ @objc public override func deprecatedPropertyMappings() -> [String: String] {
28
+ return [:]
29
+ }
30
+
31
+ @objc public override func sensitivePropertyNames() -> [String] {
32
+ return ["accessToken", "refreshToken"]
33
+ }
34
+
35
+ @objc public override func propertySpecs() -> [BGPropertySpecImpl] {
36
+ return [
37
+ BGPropertySpec(name: "strategy", type: "string"),
38
+ BGPropertySpec(name: "accessToken", type: "string"),
39
+ BGPropertySpec(name: "refreshToken", type: "string"),
40
+ BGPropertySpec(name: "refreshUrl", type: "string"),
41
+ BGPropertySpec(name: "refreshHeaders", type: "object"),
42
+ BGPropertySpec(name: "refreshPayload", type: "object"),
43
+ BGPropertySpec(name: "expires", type: "date")
44
+ ]
45
+ }
46
+
47
+ @objc public func apply(_ dict: [String: Any]) {
48
+ updateWithDictionary(dict)
49
+ }
50
+ }
@@ -0,0 +1,40 @@
1
+ import Foundation
2
+
3
+ @objc public final class BGAuthorizationEvent: NSObject {
4
+
5
+ @objc public private(set) var status: Int
6
+ @objc public private(set) var error: Error?
7
+ @objc public private(set) var response: Any?
8
+
9
+ @objc public init(response: Any?, status: Int) {
10
+ self.status = status
11
+ self.error = nil
12
+ self.response = response
13
+ super.init()
14
+ }
15
+
16
+ @objc public init(error: Error?, status: Int) {
17
+ self.status = status
18
+ self.error = error
19
+ self.response = [AnyHashable: Any]()
20
+ super.init()
21
+ }
22
+
23
+ @objc public func toDictionary() -> [String: Any] {
24
+ if let error = error {
25
+ return [
26
+ "status": status,
27
+ "success": false,
28
+ "error": (error as NSError).localizedDescription,
29
+ "response": NSNull()
30
+ ]
31
+ } else {
32
+ return [
33
+ "status": status,
34
+ "success": true,
35
+ "error": NSNull(),
36
+ "response": response ?? NSNull()
37
+ ]
38
+ }
39
+ }
40
+ }