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.
- package/BgGeolocation.podspec +39 -0
- package/LICENSE +20 -0
- package/README.md +366 -0
- package/android/build.gradle +69 -0
- package/android/src/main/AndroidManifest.xml +53 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationActivityRecognitionReceiver.kt +116 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationBootReceiver.kt +44 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationForegroundService.kt +373 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationGeofenceReceiver.kt +55 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationHeadlessTask.kt +138 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationModule.kt +1030 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationMotionStateMachine.kt +159 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationPackage.kt +31 -0
- package/android/src/main/res/drawable/bg_geo_notification.xml +9 -0
- package/ios/BgGeolocation.h +14 -0
- package/ios/BgGeolocation.mm +709 -0
- package/ios/engine/AtomicBoolean.swift +48 -0
- package/ios/engine/BGActivityChangeEvent.swift +20 -0
- package/ios/engine/BGActivityConfig.swift +71 -0
- package/ios/engine/BGAppConfig.swift +92 -0
- package/ios/engine/BGAppState.swift +147 -0
- package/ios/engine/BGAuthorization.swift +85 -0
- package/ios/engine/BGAuthorizationAlertPresenter.swift +39 -0
- package/ios/engine/BGAuthorizationConfig.swift +50 -0
- package/ios/engine/BGAuthorizationEvent.swift +40 -0
- package/ios/engine/BGBackgroundTaskManager.swift +143 -0
- package/ios/engine/BGCLRouter.swift +101 -0
- package/ios/engine/BGCallback.swift +19 -0
- package/ios/engine/BGConfig.swift +440 -0
- package/ios/engine/BGConfigModuleBase.swift +180 -0
- package/ios/engine/BGConfigOLD.swift +582 -0
- package/ios/engine/BGConnectivityChangeEvent.swift +15 -0
- package/ios/engine/BGCrashDetector.swift +122 -0
- package/ios/engine/BGCurrentPositionRequest.swift +87 -0
- package/ios/engine/BGDataStore.swift +75 -0
- package/ios/engine/BGDatabase.swift +677 -0
- package/ios/engine/BGDatabasePool.swift +220 -0
- package/ios/engine/BGDatabaseQueue.swift +215 -0
- package/ios/engine/BGDateUtils.swift +26 -0
- package/ios/engine/BGDeviceInfo.swift +54 -0
- package/ios/engine/BGDeviceManager.swift +65 -0
- package/ios/engine/BGEnabledChangeEvent.swift +11 -0
- package/ios/engine/BGEnv.swift +17 -0
- package/ios/engine/BGEventBus.swift +83 -0
- package/ios/engine/BGEventManager.swift +169 -0
- package/ios/engine/BGEventNames.swift +51 -0
- package/ios/engine/BGGeofence.swift +233 -0
- package/ios/engine/BGGeofenceDAO.swift +152 -0
- package/ios/engine/BGGeofenceEvent.swift +42 -0
- package/ios/engine/BGGeofenceLocationRequest.swift +94 -0
- package/ios/engine/BGGeofenceManager.swift +315 -0
- package/ios/engine/BGGeofenceTransition.swift +97 -0
- package/ios/engine/BGGeofencesChangeEvent.swift +26 -0
- package/ios/engine/BGGeolocationConfig.swift +136 -0
- package/ios/engine/BGHeartbeatEvent.swift +31 -0
- package/ios/engine/BGHeartbeatService.swift +51 -0
- package/ios/engine/BGHttpConfig.swift +105 -0
- package/ios/engine/BGHttpErrorCodes.swift +63 -0
- package/ios/engine/BGHttpEvent.swift +34 -0
- package/ios/engine/BGHttpRequest.swift +126 -0
- package/ios/engine/BGHttpResponse.swift +93 -0
- package/ios/engine/BGHttpService.swift +428 -0
- package/ios/engine/BGKalmanFilter.swift +105 -0
- package/ios/engine/BGLMActionNames.swift +55 -0
- package/ios/engine/BGLicenseManager.swift +26 -0
- package/ios/engine/BGLiveActivityManager.swift +327 -0
- package/ios/engine/BGLocation.swift +311 -0
- package/ios/engine/BGLocationAuthorization.swift +427 -0
- package/ios/engine/BGLocationDAO.swift +252 -0
- package/ios/engine/BGLocationErrors.swift +28 -0
- package/ios/engine/BGLocationEvent.swift +43 -0
- package/ios/engine/BGLocationFilter.swift +82 -0
- package/ios/engine/BGLocationFilterConfig.swift +57 -0
- package/ios/engine/BGLocationHelper.swift +54 -0
- package/ios/engine/BGLocationManager.swift +662 -0
- package/ios/engine/BGLocationMetricsEngine.swift +116 -0
- package/ios/engine/BGLocationRequestService.swift +459 -0
- package/ios/engine/BGLocationSatisfier.swift +14 -0
- package/ios/engine/BGLocationStreamEvent.swift +27 -0
- package/ios/engine/BGLog.swift +337 -0
- package/ios/engine/BGLogLevel.swift +26 -0
- package/ios/engine/BGLoggerConfig.swift +60 -0
- package/ios/engine/BGMotionActivity.swift +31 -0
- package/ios/engine/BGMotionActivityClassifier.swift +108 -0
- package/ios/engine/BGMotionActivityManagerAdapter.swift +40 -0
- package/ios/engine/BGMotionActivitySource.swift +46 -0
- package/ios/engine/BGMotionDetector.swift +377 -0
- package/ios/engine/BGMotionPermissionManager.swift +50 -0
- package/ios/engine/BGNativeLogger.swift +48 -0
- package/ios/engine/BGNotificaitons.swift +37 -0
- package/ios/engine/BGOdometer.swift +66 -0
- package/ios/engine/BGPersistenceConfig.swift +29 -0
- package/ios/engine/BGPolygonStreamRequest.swift +48 -0
- package/ios/engine/BGPowerSaveChangeEvent.swift +12 -0
- package/ios/engine/BGPropertySpec.swift +29 -0
- package/ios/engine/BGProviderChangeEvent.swift +31 -0
- package/ios/engine/BGQueue.swift +50 -0
- package/ios/engine/BGRPC.swift +194 -0
- package/ios/engine/BGReachability.swift +58 -0
- package/ios/engine/BGResultSet.swift +157 -0
- package/ios/engine/BGSchedule.swift +228 -0
- package/ios/engine/BGScheduleEvent.swift +13 -0
- package/ios/engine/BGScheduler.swift +116 -0
- package/ios/engine/BGSingleLocationRequest.swift +49 -0
- package/ios/engine/BGStreamLocationRequest.swift +42 -0
- package/ios/engine/BGTemplate.swift +54 -0
- package/ios/engine/BGTimerService.swift +46 -0
- package/ios/engine/BGTrackingAudioManager.swift +286 -0
- package/ios/engine/BGTrackingService.swift +879 -0
- package/ios/engine/BGWatchPositionRequest.swift +63 -0
- package/ios/engine/DatabaseQueue.swift +47 -0
- package/ios/engine/LogQuery.swift +10 -0
- package/ios/engine/SQLQuery.swift +65 -0
- package/ios/engine/TransistorAuthorizationToken.swift +182 -0
- package/ios/liveactivity/BGLiveTrackingAttributes.swift +52 -0
- package/ios/locationpush/BGLocationPushDeliverer.swift +260 -0
- package/ios/locationpush/BGLocationPushService.swift +161 -0
- package/ios/locationpush/BGLocationPushShared.swift +98 -0
- package/ios/locationpush/BGLocationPushSocketClient.swift +198 -0
- package/lib/module/NativeBgGeolocation.js +5 -0
- package/lib/module/NativeBgGeolocation.js.map +1 -0
- package/lib/module/events.js +20 -0
- package/lib/module/events.js.map +1 -0
- package/lib/module/index.js +706 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeBgGeolocation.d.ts +57 -0
- package/lib/typescript/src/NativeBgGeolocation.d.ts.map +1 -0
- package/lib/typescript/src/events.d.ts +18 -0
- package/lib/typescript/src/events.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +238 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +229 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +141 -0
- package/src/NativeBgGeolocation.ts +236 -0
- package/src/events.ts +17 -0
- package/src/index.tsx +935 -0
- 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
|
+
}
|