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,228 @@
1
+ import Foundation
2
+
3
+ @objc public final class BGSchedule: NSObject {
4
+
5
+ @objc public var days: NSMutableArray
6
+ @objc public private(set) var isLiteralDate: Bool = false
7
+ private var hasTriggered: Bool = false
8
+ private var datePattern: String
9
+ private var calendar: NSCalendar
10
+ @objc public var triggered: Bool = false
11
+ @objc public var onTime: NSDateComponents?
12
+ @objc public var onDate: Date?
13
+ @objc public var offTime: NSDateComponents?
14
+ @objc public var offDate: Date?
15
+ @objc public var trackingMode: Int = 1
16
+ @objc public var handlerBlock: (() -> Void)?
17
+
18
+ @objc public init(record: String) {
19
+ self.days = NSMutableArray()
20
+ self.triggered = false
21
+ self.hasTriggered = false
22
+ self.trackingMode = 1
23
+ self.datePattern = "^\\d{4}-\\d{2}-\\d{2}.*"
24
+
25
+ let cal = NSCalendar(calendarIdentifier: .gregorian)!
26
+ cal.locale = Locale(identifier: "en_US")
27
+ cal.timeZone = NSTimeZone.local
28
+ self.calendar = cal
29
+
30
+ let onComponents = NSDateComponents()
31
+ let offComponents = NSDateComponents()
32
+ self.onTime = onComponents
33
+ self.offTime = offComponents
34
+
35
+ super.init()
36
+
37
+ let parts = NSMutableArray(array: record.components(separatedBy: " "))
38
+ guard parts.count > 0, let part0 = parts.object(at: 0) as? String else { return }
39
+
40
+ if part0.contains("-") {
41
+ let isDate = part0.range(of: datePattern, options: .regularExpression) != nil
42
+ if isDate {
43
+ isLiteralDate = true
44
+ let dateComponents = part0.components(separatedBy: "-")
45
+ onComponents.year = Int(dateComponents[0]) ?? 0
46
+ onComponents.month = Int(dateComponents[1]) ?? 0
47
+ onComponents.day = Int(dateComponents[2]) ?? 0
48
+
49
+ if parts.count > 1, let part1 = parts.object(at: 1) as? String {
50
+ if part1.range(of: datePattern, options: .regularExpression) != nil {
51
+ offComponents.year = onComponents.year
52
+ offComponents.month = onComponents.month
53
+ offComponents.day = onComponents.day
54
+ } else {
55
+ let off = part1.components(separatedBy: "-")
56
+ offComponents.year = Int(off[0]) ?? 0
57
+ offComponents.month = Int(off[1]) ?? 0
58
+ offComponents.day = Int(off[2]) ?? 0
59
+ if dateComponents.count > 3 && off.count > 3 {
60
+ parts[1] = String(format: "%@-%@", dateComponents[3], off[3])
61
+ }
62
+ }
63
+ }
64
+ } else {
65
+ // Numeric day range "from-to".
66
+ let range = part0.components(separatedBy: "-")
67
+ let from = Int(range[0]) ?? 0
68
+ let to = Int(range[1]) ?? 0
69
+ if from <= to {
70
+ for day in from...to {
71
+ days.add(NSNumber(value: day))
72
+ }
73
+ }
74
+ }
75
+ } else {
76
+ // Comma-separated day list.
77
+ for dayStr in part0.components(separatedBy: ",") {
78
+ days.add(NSNumber(value: Int(dayStr) ?? 0))
79
+ }
80
+ }
81
+
82
+ // Parse time window from parts[1] ("HH:MM-HH:MM").
83
+ if parts.count > 1, let part1 = parts.object(at: 1) as? String {
84
+ let timeRange = part1.components(separatedBy: "-")
85
+ if timeRange.count >= 2 {
86
+ let onParts = timeRange[0].components(separatedBy: ":")
87
+ onComponents.hour = Int(onParts[0]) ?? 0
88
+ onComponents.minute = onParts.count > 1 ? (Int(onParts[1]) ?? 0) : 0
89
+ let offParts = timeRange[1].components(separatedBy: ":")
90
+ offComponents.hour = Int(offParts[0]) ?? 0
91
+ offComponents.minute = offParts.count > 1 ? (Int(offParts[1]) ?? 0) : 0
92
+ }
93
+ }
94
+
95
+ if isLiteralDate {
96
+ onDate = calendar.date(from: onComponents as DateComponents)
97
+ offDate = calendar.date(from: offComponents as DateComponents)
98
+ if let onDate = onDate, let offDate = offDate,
99
+ (offDate as NSDate).earlierDate(onDate) == offDate {
100
+ let oneDay = NSDateComponents()
101
+ oneDay.day = 1
102
+ self.offDate = calendar.date(byAdding: oneDay as DateComponents, to: offDate, options: [])
103
+ }
104
+ }
105
+
106
+ if parts.count >= 3, let part2 = parts.object(at: 2) as? String {
107
+ if part2.contains("geofence") {
108
+ trackingMode = 0
109
+ }
110
+ }
111
+ }
112
+
113
+ @objc public func evaluate() -> Date {
114
+ let now = Date()
115
+ if triggered {
116
+ if (now as NSDate).laterDate(offDate ?? now) == now {
117
+ trigger(false)
118
+ }
119
+ } else {
120
+ if let onDate = onDate, (now as NSDate).laterDate(onDate) == now {
121
+ let withinWindow = (now as NSDate).earlierDate(offDate ?? now) == now
122
+ trigger(withinWindow)
123
+ }
124
+ }
125
+ return now
126
+ }
127
+
128
+ @objc public func trigger(_ state: Bool) {
129
+ if hasTriggered && triggered == state {
130
+ return
131
+ }
132
+ let logger = BGLog.sharedInstance()
133
+ if state {
134
+ if logger.shouldLog(5) {
135
+ let message = String(format: "%@", description)
136
+ logger.log(5, tag: 3, function: "-[BGSchedule trigger:]", message: message)
137
+ }
138
+ } else {
139
+ if logger.shouldLog(3) {
140
+ let message = String(format: "%@", description)
141
+ logger.log(3, tag: 5, function: "-[BGSchedule trigger:]", message: message)
142
+ }
143
+ }
144
+ hasTriggered = true
145
+ triggered = state
146
+
147
+ let state = BGConfig.sharedInstance().toDictionary()
148
+ let event = BGScheduleEvent(schedule: self, state: state)
149
+ BGEventBus.sharedInstance().trigger(BGEventNameSchedule, payload: event)
150
+ BGEventManager.sharedInstance().trigger(BGEventNameSchedule, payload: event)
151
+ }
152
+
153
+ @objc public func make(_ components: NSDateComponents) {
154
+ guard !isLiteralDate else { return }
155
+ onTime?.year = components.year
156
+ onTime?.month = components.month
157
+ onTime?.day = components.day
158
+ onDate = calendar.date(from: (onTime ?? NSDateComponents()) as DateComponents)
159
+
160
+ offTime?.year = components.year
161
+ offTime?.month = components.month
162
+ offTime?.day = components.day
163
+ offDate = calendar.date(from: (offTime ?? NSDateComponents()) as DateComponents)
164
+
165
+ if let onDate = onDate, let offDate = offDate,
166
+ (offDate as NSDate).earlierDate(onDate) == offDate {
167
+ let oneDay = NSDateComponents()
168
+ oneDay.day = 1
169
+ self.offDate = calendar.date(byAdding: oneDay as DateComponents, to: offDate, options: [])
170
+ }
171
+ }
172
+
173
+ @objc public func isNext(_ date: Date) -> Bool {
174
+ let comps = calendar.components([.year, .month, .day, .hour, .minute, .weekday], from: date)
175
+ if !isLiteralDate {
176
+ make(comps as NSDateComponents)
177
+ if !hasDay(comps.weekday ?? 0) {
178
+ return false
179
+ }
180
+ }
181
+ guard let offDate = offDate else { return false }
182
+ return (date as NSDate).earlierDate(offDate) == date
183
+ }
184
+
185
+ @objc public func reset() {
186
+ hasTriggered = false
187
+ }
188
+
189
+ @objc public func expired() -> Bool {
190
+ let now = Date()
191
+ guard let offDate = offDate else { return false }
192
+ return (now as NSDate).laterDate(offDate) == now
193
+ }
194
+
195
+ @objc public func startsBefore(_ date: Date) -> Bool {
196
+ guard let onDate = onDate else { return false }
197
+ return (onDate as NSDate).earlierDate(date) == onDate
198
+ }
199
+
200
+ @objc public func startsAfter(_ date: Date) -> Bool {
201
+ guard let onDate = onDate else { return false }
202
+ return (onDate as NSDate).earlierDate(date) == date
203
+ }
204
+
205
+ @objc public func endsBefore(_ date: Date) -> Bool {
206
+ guard let offDate = offDate else { return false }
207
+ return (offDate as NSDate).earlierDate(date) == offDate
208
+ }
209
+
210
+ @objc public func endsAfter(_ date: Date) -> Bool {
211
+ guard let offDate = offDate else { return false }
212
+ return (offDate as NSDate).earlierDate(date) == date
213
+ }
214
+
215
+ @objc public func hasDay(_ weekday: Int) -> Bool {
216
+ return days.contains(NSNumber(value: weekday))
217
+ }
218
+
219
+ public override var description: String {
220
+ let onHour = onTime?.hour ?? 0
221
+ let onMinute = onTime?.minute ?? 0
222
+ let offHour = offTime?.hour ?? 0
223
+ let offMinute = offTime?.minute ?? 0
224
+ let daysString = days.componentsJoined(by: ",")
225
+ return String(format: "BGSchedule[triggered:%d, %02ld:%02ld - %02ld:%02ld, Days:%@, trackingMode:%d]",
226
+ triggered, onHour, onMinute, offHour, offMinute, daysString, trackingMode)
227
+ }
228
+ }
@@ -0,0 +1,13 @@
1
+ import Foundation
2
+
3
+ @objc public final class BGScheduleEvent: NSObject {
4
+
5
+ @objc public private(set) var schedule: BGSchedule?
6
+ @objc public private(set) var state: Any?
7
+
8
+ @objc public init(schedule: BGSchedule?, state: Any?) {
9
+ self.schedule = schedule
10
+ self.state = state
11
+ super.init()
12
+ }
13
+ }
@@ -0,0 +1,116 @@
1
+ import Foundation
2
+
3
+ @objc public class BGScheduler: NSObject {
4
+
5
+ private static var _sharedInstance: BGScheduler?
6
+ private static let lock = NSLock()
7
+
8
+ private var scheduleRules: [BGScheduleRule] = []
9
+ private var timer: Timer?
10
+ private var enabled: Bool = false
11
+
12
+ @objc public class func sharedInstance() -> BGScheduler {
13
+ lock.lock()
14
+ defer { lock.unlock() }
15
+ if _sharedInstance == nil {
16
+ _sharedInstance = BGScheduler()
17
+ }
18
+ return _sharedInstance!
19
+ }
20
+
21
+ @objc public override init() {
22
+ super.init()
23
+ }
24
+
25
+ @objc public func start(withSchedule schedule: [String]) -> Bool {
26
+ stop()
27
+ scheduleRules = schedule.compactMap { BGScheduleRule(rule: $0) }
28
+ guard !scheduleRules.isEmpty else { return false }
29
+ enabled = true
30
+ startTimer()
31
+ return true
32
+ }
33
+
34
+ @objc public func stop() {
35
+ timer?.invalidate()
36
+ timer = nil
37
+ enabled = false
38
+ }
39
+
40
+ @objc public func isEnabled() -> Bool {
41
+ return enabled
42
+ }
43
+
44
+ @objc public func isTracking() -> Bool {
45
+ guard enabled else { return false }
46
+ let now = Date()
47
+ return scheduleRules.contains { $0.isActiveAt(now) }
48
+ }
49
+
50
+ @objc public func nextScheduledDate() -> Date? {
51
+ let now = Date()
52
+ return scheduleRules.compactMap { $0.nextTriggerDate(after: now) }.min()
53
+ }
54
+
55
+ private func startTimer() {
56
+ timer = Timer.scheduledTimer(timeInterval: 60.0,
57
+ target: self,
58
+ selector: #selector(evaluate),
59
+ userInfo: nil,
60
+ repeats: true)
61
+ }
62
+
63
+ @objc private func evaluate() {
64
+ let tracking = isTracking()
65
+ NotificationCenter.default.post(
66
+ name: NSNotification.Name("BGSchedulerEvaluated"),
67
+ object: self,
68
+ userInfo: ["tracking": tracking]
69
+ )
70
+ }
71
+ }
72
+
73
+ private class BGScheduleRule {
74
+ let raw: String
75
+ let startHour: Int
76
+ let startMinute: Int
77
+ let endHour: Int
78
+ let endMinute: Int
79
+ let weekdays: [Int]
80
+
81
+ init?(rule: String) {
82
+ raw = rule
83
+ let parts = rule.components(separatedBy: " ")
84
+ guard parts.count >= 2 else { return nil }
85
+ let timePart = parts[0].components(separatedBy: "-")
86
+ guard timePart.count == 2 else { return nil }
87
+ let startParts = timePart[0].components(separatedBy: ":")
88
+ let endParts = timePart[1].components(separatedBy: ":")
89
+ guard startParts.count == 2, endParts.count == 2 else { return nil }
90
+ startHour = Int(startParts[0]) ?? 0
91
+ startMinute = Int(startParts[1]) ?? 0
92
+ endHour = Int(endParts[0]) ?? 0
93
+ endMinute = Int(endParts[1]) ?? 0
94
+ weekdays = parts.dropFirst().compactMap { Int($0) }
95
+ }
96
+
97
+ func isActiveAt(_ date: Date) -> Bool {
98
+ let cal = Calendar.current
99
+ let weekday = cal.component(.weekday, from: date)
100
+ if !weekdays.isEmpty && !weekdays.contains(weekday) { return false }
101
+ let hour = cal.component(.hour, from: date)
102
+ let minute = cal.component(.minute, from: date)
103
+ let current = hour * 60 + minute
104
+ let start = startHour * 60 + startMinute
105
+ let end = endHour * 60 + endMinute
106
+ if start <= end {
107
+ return current >= start && current < end
108
+ } else {
109
+ return current >= start || current < end
110
+ }
111
+ }
112
+
113
+ func nextTriggerDate(after date: Date) -> Date? {
114
+ return nil
115
+ }
116
+ }
@@ -0,0 +1,49 @@
1
+ import Foundation
2
+ import CoreLocation
3
+
4
+ @objc public class BGSingleLocationRequest: NSObject {
5
+
6
+ @objc public var type: String = "single"
7
+ @objc public var maximumAge: Double = 0
8
+ @objc public var timeout: Double = 30
9
+ @objc public var desiredAccuracy: CLLocationAccuracy = kCLLocationAccuracyBest
10
+ @objc public var allowStale: Bool = false
11
+ @objc public var samples: Int = 1
12
+ @objc public var label: String?
13
+ @objc public var persist: Bool = false
14
+ @objc public var extras: [AnyHashable: Any]?
15
+ @objc public var success: ((Any?) -> Void)?
16
+ @objc public var failure: ((Int) -> Void)?
17
+ @objc public var requestId: String = UUID().uuidString
18
+
19
+ @objc public override init() {
20
+ super.init()
21
+ }
22
+
23
+ @objc public init(
24
+ type: String,
25
+ maximumAge: Double,
26
+ timeout: Double,
27
+ desiredAccuracy: CLLocationAccuracy,
28
+ allowStale: Bool,
29
+ samples: Int,
30
+ label: String?,
31
+ persist: Bool,
32
+ extras: [AnyHashable: Any]?,
33
+ success: @escaping (Any?) -> Void,
34
+ failure: @escaping (Int) -> Void
35
+ ) {
36
+ self.type = type
37
+ self.maximumAge = maximumAge
38
+ self.timeout = timeout
39
+ self.desiredAccuracy = desiredAccuracy
40
+ self.allowStale = allowStale
41
+ self.samples = samples
42
+ self.label = label
43
+ self.persist = persist
44
+ self.extras = extras
45
+ self.success = success
46
+ self.failure = failure
47
+ super.init()
48
+ }
49
+ }
@@ -0,0 +1,42 @@
1
+ import Foundation
2
+ import CoreLocation
3
+
4
+ @objc public class BGStreamLocationRequest: NSObject {
5
+
6
+ @objc public var streamId: Int = 0
7
+ @objc public var interval: Double = 1000.0
8
+ @objc public var desiredAccuracy: CLLocationAccuracy = kCLLocationAccuracyBest
9
+ @objc public var timeout: Double = 60.0
10
+ @objc public var persist: Bool = true
11
+ @objc public var extras: [AnyHashable: Any]?
12
+ @objc public var label: String?
13
+ @objc public var success: ((Any?) -> Void)?
14
+ @objc public var failure: ((Int) -> Void)?
15
+
16
+ @objc public override init() {
17
+ super.init()
18
+ }
19
+
20
+ @objc public init(
21
+ streamId: Int,
22
+ interval: Double,
23
+ desiredAccuracy: CLLocationAccuracy,
24
+ timeout: Double,
25
+ persist: Bool,
26
+ extras: [AnyHashable: Any]?,
27
+ label: String?,
28
+ success: @escaping (Any?) -> Void,
29
+ failure: @escaping (Int) -> Void
30
+ ) {
31
+ self.streamId = streamId
32
+ self.interval = interval
33
+ self.desiredAccuracy = desiredAccuracy
34
+ self.timeout = timeout
35
+ self.persist = persist
36
+ self.extras = extras
37
+ self.label = label
38
+ self.success = success
39
+ self.failure = failure
40
+ super.init()
41
+ }
42
+ }
@@ -0,0 +1,54 @@
1
+ import Foundation
2
+
3
+ @objc public class BGTemplate: NSObject {
4
+
5
+ @objc public var name: String
6
+ @objc public var content: [String: Any]
7
+
8
+ @objc public init(name: String, content: [String: Any]) {
9
+ self.name = name
10
+ self.content = content
11
+ super.init()
12
+ }
13
+
14
+ @objc public override init() {
15
+ name = ""
16
+ content = [:]
17
+ super.init()
18
+ }
19
+
20
+ @objc public func render(with data: [String: Any]) -> [String: Any] {
21
+ var result: [String: Any] = [:]
22
+ for (key, value) in content {
23
+ if let strVal = value as? String {
24
+ result[key] = interpolate(strVal, with: data)
25
+ } else {
26
+ result[key] = value
27
+ }
28
+ }
29
+ return result
30
+ }
31
+
32
+ private func interpolate(_ template: String, with data: [String: Any]) -> String {
33
+ var result = template
34
+ let pattern = "<%=\\s*(.+?)\\s*%>"
35
+ guard let regex = try? NSRegularExpression(pattern: pattern) else { return template }
36
+ let range = NSRange(template.startIndex..., in: template)
37
+ let matches = regex.matches(in: template, range: range)
38
+ for match in matches.reversed() {
39
+ if let keyRange = Range(match.range(at: 1), in: template) {
40
+ let key = String(template[keyRange])
41
+ if let val = data[key] {
42
+ if let matchRange = Range(match.range, in: result) {
43
+ result.replaceSubrange(matchRange, with: "\(val)")
44
+ }
45
+ }
46
+ }
47
+ }
48
+ return result
49
+ }
50
+
51
+ @objc public override var description: String {
52
+ return "<BGTemplate name=\(name)>"
53
+ }
54
+ }
@@ -0,0 +1,46 @@
1
+ import Foundation
2
+
3
+ @objc public class BGTimerService: NSObject {
4
+
5
+ private var timers: [String: Timer] = [:]
6
+ private let lock = NSLock()
7
+
8
+ @objc public func scheduleTimer(
9
+ _ id: String,
10
+ interval: TimeInterval,
11
+ repeats: Bool,
12
+ block: @escaping () -> Void
13
+ ) {
14
+ lock.lock()
15
+ timers[id]?.invalidate()
16
+ let timer = Timer.scheduledTimer(withTimeInterval: interval, repeats: repeats) { _ in
17
+ block()
18
+ }
19
+ timers[id] = timer
20
+ lock.unlock()
21
+ }
22
+
23
+ @objc public func cancelTimer(_ id: String) {
24
+ lock.lock()
25
+ timers[id]?.invalidate()
26
+ timers.removeValue(forKey: id)
27
+ lock.unlock()
28
+ }
29
+
30
+ @objc public func cancelAllTimers() {
31
+ lock.lock()
32
+ timers.values.forEach { $0.invalidate() }
33
+ timers.removeAll()
34
+ lock.unlock()
35
+ }
36
+
37
+ @objc public func hasTimer(_ id: String) -> Bool {
38
+ lock.lock()
39
+ defer { lock.unlock() }
40
+ return timers[id]?.isValid ?? false
41
+ }
42
+
43
+ @objc public func isRunning(_ id: String) -> Bool {
44
+ return hasTimer(id)
45
+ }
46
+ }