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,220 @@
1
+ import Foundation
2
+
3
+ @objc public protocol BGDatabasePoolDelegate: NSObjectProtocol {
4
+ @objc optional func databasePool(_ pool: BGDatabasePool, shouldAddDatabaseToPool database: BGDatabase) -> Bool
5
+ @objc optional func databasePool(_ pool: BGDatabasePool, didAddDatabase database: BGDatabase)
6
+ }
7
+
8
+ @objc public class BGDatabasePool: NSObject {
9
+
10
+ @objc public var path: String = ""
11
+ @objc public var vfsName: String?
12
+ @objc public var openFlags: Int32 = 0
13
+ @objc public var maximumNumberOfDatabasesToCreate: Int = 5
14
+ @objc public weak var delegate: BGDatabasePoolDelegate?
15
+
16
+ private var databaseInPool: [BGDatabase] = []
17
+ private var databaseOutPool: [BGDatabase] = []
18
+ private let lockQueue = DispatchQueue(label: "BGDatabasePool.lock")
19
+ private let semaphore: DispatchSemaphore
20
+
21
+ @objc public class func databasePool(withPath path: String) -> BGDatabasePool {
22
+ return BGDatabasePool(path: path)
23
+ }
24
+
25
+ @objc public class func databasePool(withPath path: String, flags: Int32) -> BGDatabasePool {
26
+ return BGDatabasePool(path: path, flags: flags)
27
+ }
28
+
29
+ @objc public class func databasePool(withURL url: URL) -> BGDatabasePool {
30
+ return BGDatabasePool(url: url)
31
+ }
32
+
33
+ @objc public class func databasePool(withURL url: URL, flags: Int32) -> BGDatabasePool {
34
+ return BGDatabasePool(url: url, flags: flags)
35
+ }
36
+
37
+ @objc public class func databaseClass() -> AnyClass {
38
+ return BGDatabase.self
39
+ }
40
+
41
+ @objc public init(path: String) {
42
+ self.path = path
43
+ self.semaphore = DispatchSemaphore(value: 5)
44
+ super.init()
45
+ }
46
+
47
+ @objc public init(path: String, flags: Int32) {
48
+ self.path = path
49
+ self.openFlags = flags
50
+ self.semaphore = DispatchSemaphore(value: 5)
51
+ super.init()
52
+ }
53
+
54
+ @objc public init(path: String, flags: Int32, vfs: String?) {
55
+ self.path = path
56
+ self.openFlags = flags
57
+ self.vfsName = vfs
58
+ self.semaphore = DispatchSemaphore(value: 5)
59
+ super.init()
60
+ }
61
+
62
+ @objc public init(url: URL) {
63
+ self.path = url.path
64
+ self.semaphore = DispatchSemaphore(value: 5)
65
+ super.init()
66
+ }
67
+
68
+ @objc public init(url: URL, flags: Int32) {
69
+ self.path = url.path
70
+ self.openFlags = flags
71
+ self.semaphore = DispatchSemaphore(value: 5)
72
+ super.init()
73
+ }
74
+
75
+ @objc public init(url: URL, flags: Int32, vfs: String?) {
76
+ self.path = url.path
77
+ self.openFlags = flags
78
+ self.vfsName = vfs
79
+ self.semaphore = DispatchSemaphore(value: 5)
80
+ super.init()
81
+ }
82
+
83
+ @objc public override init() {
84
+ self.semaphore = DispatchSemaphore(value: 5)
85
+ super.init()
86
+ }
87
+
88
+ @objc public func countOfCheckedInDatabases() -> Int {
89
+ return executeLocked { self.databaseInPool.count }
90
+ }
91
+
92
+ @objc public func countOfCheckedOutDatabases() -> Int {
93
+ return executeLocked { self.databaseOutPool.count }
94
+ }
95
+
96
+ @objc public func countOfOpenDatabases() -> Int {
97
+ return executeLocked { self.databaseInPool.count + self.databaseOutPool.count }
98
+ }
99
+
100
+ @objc public func releaseAllDatabases() {
101
+ executeLocked {
102
+ self.databaseInPool.removeAll()
103
+ self.databaseOutPool.removeAll()
104
+ }
105
+ }
106
+
107
+ func executeLocked<T>(_ block: () -> T) -> T {
108
+ var result: T!
109
+ lockQueue.sync { result = block() }
110
+ return result
111
+ }
112
+
113
+ @objc public func executeLocked(_ block: () -> Void) {
114
+ lockQueue.sync(execute: block)
115
+ }
116
+
117
+ func db() -> BGDatabase {
118
+ semaphore.wait()
119
+ var db: BGDatabase?
120
+ executeLocked {
121
+ db = self.databaseInPool.popLast()
122
+ }
123
+ if db == nil {
124
+ db = BGDatabase(path: path)
125
+ if openFlags != 0 {
126
+ _ = db?.open(withFlags: openFlags)
127
+ } else {
128
+ _ = db?.open()
129
+ }
130
+ }
131
+ executeLocked {
132
+ if let database = db {
133
+ self.databaseOutPool.append(database)
134
+ }
135
+ }
136
+ return db!
137
+ }
138
+
139
+ @objc public func inDatabase(_ block: (BGDatabase) -> Void) {
140
+ let database = db()
141
+ block(database)
142
+ pushDatabaseBackInPool(database)
143
+ }
144
+
145
+ @objc public func beginTransaction(_ useDeferred: Bool, withBlock block: (BGDatabase, UnsafeMutablePointer<ObjCBool>) -> Void) {
146
+ inDatabase { db in
147
+ var shouldRollback = ObjCBool(false)
148
+ if useDeferred {
149
+ _ = db.beginDeferredTransaction()
150
+ } else {
151
+ _ = db.beginTransaction()
152
+ }
153
+ block(db, &shouldRollback)
154
+ if shouldRollback.boolValue {
155
+ _ = db.rollback()
156
+ } else {
157
+ _ = db.commit()
158
+ }
159
+ }
160
+ }
161
+
162
+ @objc public func inTransaction(_ block: (BGDatabase, UnsafeMutablePointer<ObjCBool>) -> Void) {
163
+ beginTransaction(false, withBlock: block)
164
+ }
165
+
166
+ @objc public func inDeferredTransaction(_ block: (BGDatabase, UnsafeMutablePointer<ObjCBool>) -> Void) {
167
+ beginTransaction(true, withBlock: block)
168
+ }
169
+
170
+ @objc public func inImmediateTransaction(_ block: (BGDatabase, UnsafeMutablePointer<ObjCBool>) -> Void) {
171
+ inDatabase { db in
172
+ var shouldRollback = ObjCBool(false)
173
+ _ = db.beginImmediateTransaction()
174
+ block(db, &shouldRollback)
175
+ if shouldRollback.boolValue {
176
+ _ = db.rollback()
177
+ } else {
178
+ _ = db.commit()
179
+ }
180
+ }
181
+ }
182
+
183
+ @objc public func inExclusiveTransaction(_ block: (BGDatabase, UnsafeMutablePointer<ObjCBool>) -> Void) {
184
+ inDatabase { db in
185
+ var shouldRollback = ObjCBool(false)
186
+ _ = db.beginExclusiveTransaction()
187
+ block(db, &shouldRollback)
188
+ if shouldRollback.boolValue {
189
+ _ = db.rollback()
190
+ } else {
191
+ _ = db.commit()
192
+ }
193
+ }
194
+ }
195
+
196
+ @objc public func inSavePoint(_ block: (BGDatabase, UnsafeMutablePointer<ObjCBool>) -> Void) -> Error? {
197
+ inDatabase { db in
198
+ var shouldRollback = ObjCBool(false)
199
+ let name = "sp_\(arc4random())"
200
+ _ = db.startSavePoint(withName: name, error: nil)
201
+ block(db, &shouldRollback)
202
+ if shouldRollback.boolValue {
203
+ _ = db.rollbackToSavePoint(withName: name, error: nil)
204
+ } else {
205
+ _ = db.releaseSavePoint(withName: name, error: nil)
206
+ }
207
+ }
208
+ return nil
209
+ }
210
+
211
+ @objc public func pushDatabaseBackInPool(_ database: BGDatabase) {
212
+ executeLocked {
213
+ if let idx = self.databaseOutPool.firstIndex(where: { $0 === database }) {
214
+ self.databaseOutPool.remove(at: idx)
215
+ }
216
+ self.databaseInPool.append(database)
217
+ }
218
+ semaphore.signal()
219
+ }
220
+ }
@@ -0,0 +1,215 @@
1
+ import Foundation
2
+
3
+ @objc public class BGDatabaseQueue: NSObject {
4
+
5
+ @objc public var path: String = ""
6
+ @objc public var vfsName: String?
7
+ @objc public var openFlags: Int32 = 0
8
+
9
+ private var db: BGDatabase?
10
+ private let queue: DispatchQueue
11
+ private static let kQueueKey = DispatchSpecificKey<BGDatabaseQueue>()
12
+
13
+ @objc public class func databaseQueue(withPath path: String) -> BGDatabaseQueue {
14
+ return BGDatabaseQueue(path: path)
15
+ }
16
+
17
+ @objc public class func databaseQueue(withPath path: String, flags: Int32) -> BGDatabaseQueue {
18
+ return BGDatabaseQueue(path: path, flags: flags)
19
+ }
20
+
21
+ @objc public class func databaseQueue(withURL url: URL) -> BGDatabaseQueue {
22
+ return BGDatabaseQueue(url: url)
23
+ }
24
+
25
+ @objc public class func databaseQueue(withURL url: URL, flags: Int32) -> BGDatabaseQueue {
26
+ return BGDatabaseQueue(url: url, flags: flags)
27
+ }
28
+
29
+ @objc public class func databaseClass() -> AnyClass {
30
+ return BGDatabase.self
31
+ }
32
+
33
+ @objc public init(path: String) {
34
+ self.path = path
35
+ self.queue = DispatchQueue(label: "BGDatabaseQueue.\(path)")
36
+ super.init()
37
+ openDatabase()
38
+ }
39
+
40
+ @objc public init(path: String, flags: Int32) {
41
+ self.path = path
42
+ self.openFlags = flags
43
+ self.queue = DispatchQueue(label: "BGDatabaseQueue.\(path)")
44
+ super.init()
45
+ openDatabase()
46
+ }
47
+
48
+ @objc public init(path: String, flags: Int32, vfs: String?) {
49
+ self.path = path
50
+ self.openFlags = flags
51
+ self.vfsName = vfs
52
+ self.queue = DispatchQueue(label: "BGDatabaseQueue.\(path)")
53
+ super.init()
54
+ openDatabase()
55
+ }
56
+
57
+ @objc public init(url: URL) {
58
+ self.path = url.path
59
+ self.queue = DispatchQueue(label: "BGDatabaseQueue.\(url.path)")
60
+ super.init()
61
+ openDatabase()
62
+ }
63
+
64
+ @objc public init(url: URL, flags: Int32) {
65
+ self.path = url.path
66
+ self.openFlags = flags
67
+ self.queue = DispatchQueue(label: "BGDatabaseQueue.\(url.path)")
68
+ super.init()
69
+ openDatabase()
70
+ }
71
+
72
+ @objc public init(url: URL, flags: Int32, vfs: String?) {
73
+ self.path = url.path
74
+ self.openFlags = flags
75
+ self.vfsName = vfs
76
+ self.queue = DispatchQueue(label: "BGDatabaseQueue.\(url.path)")
77
+ super.init()
78
+ openDatabase()
79
+ }
80
+
81
+ @objc public override init() {
82
+ self.queue = DispatchQueue(label: "BGDatabaseQueue.default")
83
+ super.init()
84
+ }
85
+
86
+ private func openDatabase() {
87
+ let database = BGDatabase(path: path)
88
+ if openFlags != 0 {
89
+ _ = database.open(withFlags: openFlags)
90
+ } else {
91
+ _ = database.open()
92
+ }
93
+ db = database
94
+ queue.setSpecific(key: BGDatabaseQueue.kQueueKey, value: self)
95
+ }
96
+
97
+ @objc public func database() -> BGDatabase? {
98
+ return db
99
+ }
100
+
101
+ @objc public func close() {
102
+ queue.sync {
103
+ self.db?.close()
104
+ self.db = nil
105
+ }
106
+ }
107
+
108
+ @objc public func interrupt() {
109
+ db?.interrupt()
110
+ }
111
+
112
+ @objc public func inDatabase(_ block: (BGDatabase) -> Void) {
113
+ queue.sync {
114
+ guard let database = self.db else { return }
115
+ block(database)
116
+ if database.hasOpenResultSets() {
117
+ database.closeOpenResultSets()
118
+ }
119
+ }
120
+ }
121
+
122
+ @objc public func beginTransaction(_ useDeferred: Bool, withBlock block: (BGDatabase, UnsafeMutablePointer<ObjCBool>) -> Void) {
123
+ queue.sync {
124
+ guard let database = self.db else { return }
125
+ var shouldRollback = ObjCBool(false)
126
+ if useDeferred {
127
+ _ = database.beginDeferredTransaction()
128
+ } else {
129
+ _ = database.beginTransaction()
130
+ }
131
+ block(database, &shouldRollback)
132
+ if shouldRollback.boolValue {
133
+ _ = database.rollback()
134
+ } else {
135
+ _ = database.commit()
136
+ }
137
+ }
138
+ }
139
+
140
+ @objc public func inTransaction(_ block: (BGDatabase, UnsafeMutablePointer<ObjCBool>) -> Void) {
141
+ beginTransaction(false, withBlock: block)
142
+ }
143
+
144
+ @objc public func inDeferredTransaction(_ block: (BGDatabase, UnsafeMutablePointer<ObjCBool>) -> Void) {
145
+ beginTransaction(true, withBlock: block)
146
+ }
147
+
148
+ @objc public func inImmediateTransaction(_ block: (BGDatabase, UnsafeMutablePointer<ObjCBool>) -> Void) {
149
+ queue.sync {
150
+ guard let database = self.db else { return }
151
+ var shouldRollback = ObjCBool(false)
152
+ _ = database.beginImmediateTransaction()
153
+ block(database, &shouldRollback)
154
+ if shouldRollback.boolValue {
155
+ _ = database.rollback()
156
+ } else {
157
+ _ = database.commit()
158
+ }
159
+ }
160
+ }
161
+
162
+ @objc public func inExclusiveTransaction(_ block: (BGDatabase, UnsafeMutablePointer<ObjCBool>) -> Void) {
163
+ queue.sync {
164
+ guard let database = self.db else { return }
165
+ var shouldRollback = ObjCBool(false)
166
+ _ = database.beginExclusiveTransaction()
167
+ block(database, &shouldRollback)
168
+ if shouldRollback.boolValue {
169
+ _ = database.rollback()
170
+ } else {
171
+ _ = database.commit()
172
+ }
173
+ }
174
+ }
175
+
176
+ @objc public func inSavePoint(_ block: (BGDatabase, UnsafeMutablePointer<ObjCBool>) -> Void) -> Error? {
177
+ queue.sync {
178
+ guard let database = self.db else { return }
179
+ var shouldRollback = ObjCBool(false)
180
+ let name = "sp_\(arc4random())"
181
+ _ = database.startSavePoint(withName: name, error: nil)
182
+ block(database, &shouldRollback)
183
+ if shouldRollback.boolValue {
184
+ _ = database.rollbackToSavePoint(withName: name, error: nil)
185
+ } else {
186
+ _ = database.releaseSavePoint(withName: name, error: nil)
187
+ }
188
+ }
189
+ return nil
190
+ }
191
+
192
+ @objc public func checkpoint(_ checkpointMode: Int32, error: UnsafeMutablePointer<NSError?>?) -> Bool {
193
+ var result = false
194
+ queue.sync {
195
+ result = self.db?.checkpoint(checkpointMode, error: error) ?? false
196
+ }
197
+ return result
198
+ }
199
+
200
+ @objc public func checkpoint(_ checkpointMode: Int32, name: String?, error: UnsafeMutablePointer<NSError?>?) -> Bool {
201
+ var result = false
202
+ queue.sync {
203
+ result = self.db?.checkpoint(checkpointMode, name: name, error: error) ?? false
204
+ }
205
+ return result
206
+ }
207
+
208
+ @objc public func checkpoint(_ checkpointMode: Int32, name: String?, logFrameCount: UnsafeMutablePointer<Int32>?, checkpointCount: UnsafeMutablePointer<Int32>?, error: UnsafeMutablePointer<NSError?>?) -> Bool {
209
+ var result = false
210
+ queue.sync {
211
+ result = self.db?.checkpoint(checkpointMode, name: name, logFrameCount: logFrameCount, checkpointCount: checkpointCount, error: error) ?? false
212
+ }
213
+ return result
214
+ }
215
+ }
@@ -0,0 +1,26 @@
1
+ import Foundation
2
+
3
+ @objc public final class BGDateUtils: NSObject {
4
+
5
+ private static let iso8601Formatter: ISO8601DateFormatter = {
6
+ let formatter = ISO8601DateFormatter()
7
+ formatter.formatOptions = ISO8601DateFormatter.Options(rawValue: 0xf73)
8
+ formatter.timeZone = TimeZone(abbreviation: "UTC")
9
+ return formatter
10
+ }()
11
+
12
+ private static let iso8601ParseFormatter: ISO8601DateFormatter = {
13
+ let formatter = ISO8601DateFormatter()
14
+ formatter.formatOptions = ISO8601DateFormatter.Options(rawValue: 0xf73)
15
+ formatter.timeZone = TimeZone(abbreviation: "UTC")
16
+ return formatter
17
+ }()
18
+
19
+ @objc public class func iso8601String(from date: Date) -> String {
20
+ return iso8601Formatter.string(from: date)
21
+ }
22
+
23
+ @objc public class func date(fromISO8601String string: String) -> Date? {
24
+ return iso8601ParseFormatter.date(from: string)
25
+ }
26
+ }
@@ -0,0 +1,54 @@
1
+ import Foundation
2
+ #if canImport(UIKit)
3
+ import UIKit
4
+ #endif
5
+
6
+ @objc public final class BGDeviceInfo: NSObject {
7
+
8
+ @objc public var model: String?
9
+ @objc public var manufacturer: String?
10
+ @objc public var platform: String?
11
+ @objc public var version: String?
12
+
13
+ @objc public static let sharedInstance = BGDeviceInfo()
14
+
15
+ @objc public override init() {
16
+ super.init()
17
+ let device = UIDevice.current
18
+ self.model = getDeviceId()
19
+ self.platform = device.systemName
20
+ self.manufacturer = "Apple"
21
+ self.version = device.systemVersion
22
+ }
23
+
24
+ @objc public func toDictionary() -> [String: Any] {
25
+ return [
26
+ "model": model ?? "",
27
+ "platform": platform ?? "",
28
+ "manufacturer": "Apple",
29
+ "version": version ?? "",
30
+ "framework": "native"
31
+ ]
32
+ }
33
+
34
+ @objc public func toDictionary(_ framework: String) -> [String: Any] {
35
+ var dict = toDictionary()
36
+ dict["framework"] = framework
37
+ return dict
38
+ }
39
+
40
+ @objc public func getDeviceId() -> String {
41
+ var systemInfo = utsname()
42
+ uname(&systemInfo)
43
+ let machine = withUnsafePointer(to: &systemInfo.machine) {
44
+ $0.withMemoryRebound(to: CChar.self, capacity: 1) {
45
+ String(cString: $0)
46
+ }
47
+ }
48
+ if machine == "i386" || machine == "x86_64" {
49
+ let simulatorModel = ProcessInfo.processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"] ?? ""
50
+ return String(format: "%s(%@)", simulatorModel, machine)
51
+ }
52
+ return machine
53
+ }
54
+ }
@@ -0,0 +1,65 @@
1
+ import Foundation
2
+ #if canImport(UIKit)
3
+ import UIKit
4
+ #endif
5
+
6
+ @objc public final class BGDeviceManager: NSObject {
7
+
8
+ @objc public static let sharedInstance = BGDeviceManager()
9
+
10
+ @objc public override init() {
11
+ super.init()
12
+ }
13
+
14
+ @objc public func startMonitoring() {
15
+ let logger = BGLog.sharedInstance()
16
+ if logger.shouldLog(3) {
17
+ logger.log(3, tag: 4, function: "-[BGDeviceManager startMonitoring]", message: "")
18
+ }
19
+ UIDevice.current.isBatteryMonitoringEnabled = false
20
+ UIDevice.current.isBatteryMonitoringEnabled = true
21
+
22
+ NotificationCenter.default.removeObserver(self,
23
+ name: NSNotification.Name.NSProcessInfoPowerStateDidChange, object: nil)
24
+ NotificationCenter.default.addObserver(self,
25
+ selector: #selector(didChangePowerMode(_:)),
26
+ name: NSNotification.Name.NSProcessInfoPowerStateDidChange, object: nil)
27
+ }
28
+
29
+ @objc public func stopMonitoring() {
30
+ let logger = BGLog.sharedInstance()
31
+ if logger.shouldLog(3) {
32
+ logger.log(3, tag: 5, function: "-[BGDeviceManager stopMonitoring]", message: "")
33
+ }
34
+ UIDevice.current.isBatteryMonitoringEnabled = false
35
+ NotificationCenter.default.removeObserver(self,
36
+ name: NSNotification.Name.NSProcessInfoPowerStateDidChange, object: nil)
37
+ }
38
+
39
+ @objc public func batteryLevel() -> Float {
40
+ return UIDevice.current.batteryLevel
41
+ }
42
+
43
+ @objc public func batteryState() -> Int {
44
+ return UIDevice.current.batteryState.rawValue
45
+ }
46
+
47
+ @objc public func isLowPowerMode() -> Bool {
48
+ return ProcessInfo.processInfo.isLowPowerModeEnabled
49
+ }
50
+
51
+ @objc public func didChangePowerMode(_ notification: Notification) {
52
+ let lowPower = isLowPowerMode()
53
+ let logger = BGLog.sharedInstance()
54
+ if logger.shouldLog(3) {
55
+ let message = String(format: "%@", lowPower ? "ENABLED" : "DISABLED")
56
+ logger.log(3, tag: 0, function: "-[BGDeviceManager didChangePowerMode:]", message: message)
57
+ }
58
+ let payload = BGPowerSaveChangeEvent()
59
+ BGEventBus.sharedInstance().trigger(BGEventNamePowerSaveChange, payload: payload)
60
+ }
61
+
62
+ deinit {
63
+ NotificationCenter.default.removeObserver(self)
64
+ }
65
+ }
@@ -0,0 +1,11 @@
1
+ import Foundation
2
+
3
+ @objc public final class BGEnabledChangeEvent: NSObject {
4
+
5
+ @objc public private(set) var enabled: Bool
6
+
7
+ @objc public init(enabled: Bool) {
8
+ self.enabled = enabled
9
+ super.init()
10
+ }
11
+ }
@@ -0,0 +1,17 @@
1
+ import Foundation
2
+
3
+ @objc public final class BGEnv: NSObject {
4
+
5
+ @objc public var isTesting: Bool = false
6
+
7
+ @objc public static let sharedInstance = BGEnv()
8
+
9
+ @objc public override init() {
10
+ super.init()
11
+ let environment = ProcessInfo.processInfo.environment
12
+ let xpcServiceName = environment["XPC_SERVICE_NAME"]
13
+ if let xpcServiceName = xpcServiceName, xpcServiceName.hasSuffix("xctest") {
14
+ self.isTesting = true
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,83 @@
1
+ import Foundation
2
+
3
+ public typealias BGEventBusListener = (_ payload: Any?) -> Void
4
+
5
+ @objc public class BGEventBus: NSObject {
6
+
7
+ private static var _sharedInstance: BGEventBus?
8
+ private static let lock = NSLock()
9
+
10
+ @objc public var listenersByEvent: NSMutableDictionary = NSMutableDictionary()
11
+ @objc public var locked: Bool = false
12
+ @objc public var q: DispatchQueue = DispatchQueue(label: "com.transistorsoft.eventbus", attributes: .concurrent)
13
+
14
+ @objc public class func sharedInstance() -> BGEventBus {
15
+ lock.lock()
16
+ defer { lock.unlock() }
17
+ if _sharedInstance == nil {
18
+ _sharedInstance = BGEventBus()
19
+ }
20
+ return _sharedInstance!
21
+ }
22
+
23
+ @objc public func initPrivate() {
24
+ q = DispatchQueue(label: "com.transistorsoft.eventbus", attributes: .concurrent)
25
+ listenersByEvent = NSMutableDictionary()
26
+ }
27
+
28
+ @objc public func isLocked() -> Bool { return locked }
29
+
30
+ @objc public func lock() { locked = true }
31
+
32
+ @objc public func _isOnQueue() -> Bool {
33
+ return false
34
+ }
35
+
36
+ @objc public func on(_ event: String, listener: @escaping BGEventBusListener) -> String {
37
+ let token = UUID().uuidString
38
+ q.async(flags: .barrier) {
39
+ var listeners = self.listenersByEvent[event] as? [[String: Any]] ?? []
40
+ listeners.append(["token": token, "listener": listener])
41
+ self.listenersByEvent[event] = listeners
42
+ }
43
+ return token
44
+ }
45
+
46
+ @objc public func off(_ event: String, token: String) {
47
+ q.async(flags: .barrier) {
48
+ var listeners = self.listenersByEvent[event] as? [[String: Any]] ?? []
49
+ listeners.removeAll { ($0["token"] as? String) == token }
50
+ self.listenersByEvent[event] = listeners
51
+ }
52
+ }
53
+
54
+ @objc public func offAll(_ event: String) {
55
+ q.async(flags: .barrier) {
56
+ self.listenersByEvent.removeObject(forKey: event)
57
+ }
58
+ }
59
+
60
+ @objc public func offAll() {
61
+ q.async(flags: .barrier) {
62
+ self.listenersByEvent.removeAllObjects()
63
+ }
64
+ }
65
+
66
+ @objc public func emit(_ event: String, payload: Any?) {
67
+ q.sync {
68
+ guard let listeners = self.listenersByEvent[event] as? [[String: Any]] else { return }
69
+ for entry in listeners {
70
+ if let fn = entry["listener"] as? BGEventBusListener {
71
+ fn(payload)
72
+ }
73
+ }
74
+ }
75
+ }
76
+
77
+ @objc public func trigger(_ event: String, payload: Any?) {
78
+ emit(event, payload: payload)
79
+ }
80
+
81
+ public func setListenersByEvent(_ dict: NSMutableDictionary) { listenersByEvent = dict }
82
+ public func setLocked(_ val: Bool) { locked = val }
83
+ }