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,29 @@
1
+ import Foundation
2
+
3
+ @objc public class BGPropertySpecObject: NSObject {
4
+
5
+ @objc public var name: String
6
+ @objc public var type: String
7
+ @objc public var defaultValue: Any?
8
+ @objc public var isOptional: Bool = true
9
+ @objc public var isPrivate: Bool = false
10
+
11
+ @objc public init(name: String, type: String, defaultValue: Any? = nil) {
12
+ self.name = name
13
+ self.type = type
14
+ self.defaultValue = defaultValue
15
+ super.init()
16
+ }
17
+
18
+ @objc public func setValue(_ value: Any?, onObject obj: AnyObject, validate: Bool) {
19
+ obj.setValue(value, forKey: name)
20
+ }
21
+
22
+ @objc public func getValue(fromObject obj: AnyObject) -> Any? {
23
+ return obj.value(forKey: name)
24
+ }
25
+
26
+ @objc public override var description: String {
27
+ return "<BGPropertySpec name=\(name) type=\(type)>"
28
+ }
29
+ }
@@ -0,0 +1,31 @@
1
+ import Foundation
2
+
3
+ @objc public final class BGProviderChangeEvent: NSObject {
4
+
5
+ @objc public private(set) var gps: Bool
6
+ @objc public private(set) var network: Bool
7
+ @objc public private(set) var enabled: Bool
8
+ @objc public private(set) var status: Int32
9
+ @objc public private(set) var accuracyAuthorization: Int
10
+
11
+ @objc public override init() {
12
+ let manager = BGLocationManager.sharedInstance()
13
+ let auth = BGLocationAuthorization.sharedInstance()
14
+ self.gps = true
15
+ self.network = true
16
+ self.status = Int32(auth.authorizationStatus.rawValue)
17
+ self.enabled = manager.enabled
18
+ self.accuracyAuthorization = auth.accuracyAuthorization
19
+ super.init()
20
+ }
21
+
22
+ @objc public func toDictionary() -> [String: Any] {
23
+ return [
24
+ "enabled": enabled,
25
+ "network": network,
26
+ "gps": gps,
27
+ "status": Int(status),
28
+ "accuracyAuthorization": accuracyAuthorization
29
+ ]
30
+ }
31
+ }
@@ -0,0 +1,50 @@
1
+ import Foundation
2
+
3
+ @objc public class BGQueue: NSObject {
4
+
5
+ private var items: [Any] = []
6
+ private let lock = NSLock()
7
+
8
+ @objc public func enqueue(_ item: Any) {
9
+ lock.lock()
10
+ items.append(item)
11
+ lock.unlock()
12
+ }
13
+
14
+ @objc public func dequeue() -> Any? {
15
+ lock.lock()
16
+ defer { lock.unlock() }
17
+ guard !items.isEmpty else { return nil }
18
+ return items.removeFirst()
19
+ }
20
+
21
+ @objc public func peek() -> Any? {
22
+ lock.lock()
23
+ defer { lock.unlock() }
24
+ return items.first
25
+ }
26
+
27
+ @objc public func isEmpty() -> Bool {
28
+ lock.lock()
29
+ defer { lock.unlock() }
30
+ return items.isEmpty
31
+ }
32
+
33
+ @objc public func count() -> Int {
34
+ lock.lock()
35
+ defer { lock.unlock() }
36
+ return items.count
37
+ }
38
+
39
+ @objc public func clear() {
40
+ lock.lock()
41
+ items.removeAll()
42
+ lock.unlock()
43
+ }
44
+
45
+ @objc public func allItems() -> [Any] {
46
+ lock.lock()
47
+ defer { lock.unlock() }
48
+ return items
49
+ }
50
+ }
@@ -0,0 +1,194 @@
1
+ import Foundation
2
+
3
+ @objc public class BGRPCAction: NSObject {
4
+
5
+ @objc public var command: String = ""
6
+ @objc public var args: [String: Any]?
7
+ @objc public var callback: String?
8
+
9
+ @objc public init(array: [Any]) {
10
+ if array.count > 0 { command = array[0] as? String ?? "" }
11
+ if array.count > 1 { args = array[1] as? [String: Any] }
12
+ if array.count > 2 { callback = array[2] as? String }
13
+ super.init()
14
+ }
15
+
16
+ @objc public override init() {
17
+ super.init()
18
+ }
19
+
20
+ @objc public override var description: String {
21
+ return "<BGRPCAction command=\(command)>"
22
+ }
23
+
24
+ @objc public func ensureArgs(_ key: String) -> Bool {
25
+ return args?[key] != nil
26
+ }
27
+
28
+ @objc public func execute(_ locationManager: AnyObject) {
29
+ switch command {
30
+ case "start":
31
+ start(locationManager)
32
+ case "stop":
33
+ stop(locationManager)
34
+ case "changePace":
35
+ changePace(locationManager)
36
+ case "setConfig":
37
+ setConfig(locationManager)
38
+ case "addGeofence":
39
+ addGeofence(locationManager)
40
+ case "addGeofences":
41
+ addGeofences(locationManager)
42
+ case "removeGeofence":
43
+ removeGeofence(locationManager)
44
+ case "removeGeofences":
45
+ removeGeofences(locationManager)
46
+ case "startGeofences":
47
+ startGeofences(locationManager)
48
+ case "startSchedule":
49
+ startSchedule(locationManager)
50
+ case "stopSchedule":
51
+ stopSchedule(locationManager)
52
+ case "setOdometer":
53
+ setOdometer(locationManager)
54
+ case "uploadLog":
55
+ uploadLog(locationManager)
56
+ case "ban":
57
+ ban(locationManager)
58
+ default:
59
+ break
60
+ }
61
+ }
62
+
63
+ @objc public func start(_ lm: AnyObject) {
64
+ lm.perform(NSSelectorFromString("start"))
65
+ }
66
+
67
+ @objc public func stop(_ lm: AnyObject) {
68
+ lm.perform(NSSelectorFromString("stop"))
69
+ }
70
+
71
+ @objc public func changePace(_ lm: AnyObject) {
72
+ guard let isMoving = args?["isMoving"] as? Bool else { return }
73
+ lm.perform(NSSelectorFromString("changePace:"), with: NSNumber(value: isMoving))
74
+ }
75
+
76
+ @objc public func setConfig(_ lm: AnyObject) {
77
+ guard let config = args else { return }
78
+ lm.perform(NSSelectorFromString("setConfig:"), with: config)
79
+ }
80
+
81
+ @objc public func addGeofence(_ lm: AnyObject) {
82
+ guard let geofence = args else { return }
83
+ lm.perform(NSSelectorFromString("addGeofence:"), with: geofence)
84
+ }
85
+
86
+ @objc public func addGeofences(_ lm: AnyObject) {
87
+ guard let geofences = args?["geofences"] as? [[String: Any]] else { return }
88
+ lm.perform(NSSelectorFromString("addGeofences:"), with: geofences)
89
+ }
90
+
91
+ @objc public func removeGeofence(_ lm: AnyObject) {
92
+ guard let identifier = args?["identifier"] as? String else { return }
93
+ lm.perform(NSSelectorFromString("removeGeofence:"), with: identifier)
94
+ }
95
+
96
+ @objc public func removeGeofences(_ lm: AnyObject) {
97
+ lm.perform(NSSelectorFromString("removeGeofences"))
98
+ }
99
+
100
+ @objc public func startGeofences(_ lm: AnyObject) {
101
+ lm.perform(NSSelectorFromString("startGeofences"))
102
+ }
103
+
104
+ @objc public func startSchedule(_ lm: AnyObject) {
105
+ lm.perform(NSSelectorFromString("startSchedule"))
106
+ }
107
+
108
+ @objc public func stopSchedule(_ lm: AnyObject) {
109
+ lm.perform(NSSelectorFromString("stopSchedule"))
110
+ }
111
+
112
+ @objc public func setOdometer(_ lm: AnyObject) {
113
+ guard let value = args?["odometer"] as? Double else { return }
114
+ lm.perform(NSSelectorFromString("setOdometer:"), with: NSNumber(value: value))
115
+ }
116
+
117
+ @objc public func uploadLog(_ lm: AnyObject) {
118
+ lm.perform(NSSelectorFromString("uploadLog"))
119
+ }
120
+
121
+ @objc public func ban(_ lm: AnyObject) {
122
+ }
123
+
124
+ @objc public func buildGeofence(_ dict: [String: Any]) -> BGGeofence? {
125
+ guard let id = dict["identifier"] as? String else { return nil }
126
+ let lat = dict["latitude"] as? Double ?? 0
127
+ let lng = dict["longitude"] as? Double ?? 0
128
+ let radius = dict["radius"] as? Double ?? 200
129
+ let entry = dict["notifyOnEntry"] as? Bool ?? true
130
+ let exit = dict["notifyOnExit"] as? Bool ?? true
131
+ let dwell = dict["notifyOnDwell"] as? Bool ?? false
132
+ let loiteringDelay = dict["loiteringDelay"] as? Double ?? 0
133
+ let extras = dict["extras"] as? [String: Any]
134
+ return BGGeofence.circle(withIdentifier: id, radius: radius, latitude: lat, longitude: lng, notifyOnEntry: entry, notifyOnExit: exit, notifyOnDwell: dwell, loiteringDelay: loiteringDelay, extras: extras)
135
+ }
136
+ }
137
+
138
+ @objc public class BGRPC: NSObject {
139
+
140
+ private static var _sharedInstance: BGRPC?
141
+ private static let lock = NSLock()
142
+
143
+ @objc public var jsonKey: String = "rpc"
144
+ @objc public var actions: [BGRPCAction] = []
145
+
146
+ private let queue = DispatchQueue(label: "BGRPC.queue")
147
+
148
+ @objc public class func sharedInstance() -> BGRPC {
149
+ lock.lock()
150
+ defer { lock.unlock() }
151
+ if _sharedInstance == nil {
152
+ _sharedInstance = BGRPC()
153
+ }
154
+ return _sharedInstance!
155
+ }
156
+
157
+ @objc public override init() {
158
+ super.init()
159
+ }
160
+
161
+ @objc public func ingestHTTPResponse(withData data: Data, contentType: String) {
162
+ guard contentType.contains("application/json"),
163
+ let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
164
+ let rpcArray = json[jsonKey] as? [[Any]] else { return }
165
+
166
+ queue.async {
167
+ for item in rpcArray {
168
+ let action = BGRPCAction(array: item)
169
+ self.actions.append(action)
170
+ }
171
+ self.drainLocked()
172
+ }
173
+ }
174
+
175
+ @objc public func run(_ action: BGRPCAction) {
176
+ queue.async {
177
+ self.actions.append(action)
178
+ self.drainLocked()
179
+ }
180
+ }
181
+
182
+ @objc public func drainLocked() {
183
+ let pending = actions
184
+ actions.removeAll()
185
+ for action in pending {
186
+ NotificationCenter.default.post(name: NSNotification.Name("BGRPCAction"), object: action)
187
+ }
188
+ }
189
+
190
+ @objc public func emitRPCError(withCode code: Int, reason: String, userInfo: [String: Any]?) {
191
+ let error = NSError(domain: "BGRPC", code: code, userInfo: [NSLocalizedDescriptionKey: reason])
192
+ NotificationCenter.default.post(name: NSNotification.Name("BGRPCError"), object: error)
193
+ }
194
+ }
@@ -0,0 +1,58 @@
1
+ import Foundation
2
+ import SystemConfiguration
3
+
4
+ public typealias BGReachabilityCallback = (_ hasConnection: Bool) -> Void
5
+
6
+ @objc public class BGReachability: NSObject {
7
+
8
+ private var reachability: SCNetworkReachability?
9
+ private var callback: BGReachabilityCallback?
10
+ private var isMonitoring: Bool = false
11
+
12
+ @objc public class func reachability(forHostName host: String) -> BGReachability {
13
+ return BGReachability(host: host)
14
+ }
15
+
16
+ @objc public init(host: String) {
17
+ reachability = SCNetworkReachabilityCreateWithName(nil, host)
18
+ super.init()
19
+ }
20
+
21
+ @objc public override init() {
22
+ var addr = sockaddr_in()
23
+ addr.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
24
+ addr.sin_family = sa_family_t(AF_INET)
25
+ reachability = withUnsafePointer(to: &addr) {
26
+ $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
27
+ SCNetworkReachabilityCreateWithAddress(nil, $0)
28
+ }
29
+ }
30
+ super.init()
31
+ }
32
+
33
+ @objc public func startMonitoring(callback: @escaping BGReachabilityCallback) {
34
+ self.callback = callback
35
+ isMonitoring = true
36
+ checkReachability()
37
+ }
38
+
39
+ @objc public func stopMonitoring() {
40
+ isMonitoring = false
41
+ callback = nil
42
+ }
43
+
44
+ @objc public func isReachable() -> Bool {
45
+ guard let reachability = reachability else { return false }
46
+ var flags = SCNetworkReachabilityFlags()
47
+ SCNetworkReachabilityGetFlags(reachability, &flags)
48
+ return flags.contains(.reachable) && !flags.contains(.connectionRequired)
49
+ }
50
+
51
+ private func checkReachability() {
52
+ callback?(isReachable())
53
+ }
54
+
55
+ @objc public func hasNetworkConnection() -> Bool {
56
+ return isReachable()
57
+ }
58
+ }
@@ -0,0 +1,157 @@
1
+ import Foundation
2
+
3
+ @objc public class BGResultSet: NSObject {
4
+
5
+ private var rows: [[String: Any]] = []
6
+ private var index: Int = -1
7
+ private var columnNames: [String] = []
8
+
9
+ // Properties used by BGDatabase for sqlite statement management
10
+ @objc public var statement: BGStatement?
11
+ @objc public weak var parentDB: AnyObject?
12
+
13
+ @objc public init(rows: [[String: Any]]) {
14
+ self.rows = rows
15
+ super.init()
16
+ }
17
+
18
+ @objc public override init() {
19
+ super.init()
20
+ }
21
+
22
+ @objc public func next() -> Bool {
23
+ index += 1
24
+ return index < rows.count
25
+ }
26
+
27
+ @objc public func close() {
28
+ index = -1
29
+ }
30
+
31
+ @objc public func hasAnotherRow() -> Bool {
32
+ return (index + 1) < rows.count
33
+ }
34
+
35
+ @objc public func count() -> Int {
36
+ return rows.count
37
+ }
38
+
39
+ @objc public func string(forColumn column: String) -> String? {
40
+ guard index >= 0 && index < rows.count else { return nil }
41
+ return rows[index][column] as? String
42
+ }
43
+
44
+ @objc public func int(forColumn column: String) -> Int32 {
45
+ guard index >= 0 && index < rows.count else { return 0 }
46
+ return rows[index][column] as? Int32 ?? 0
47
+ }
48
+
49
+ @objc public func long(forColumn column: String) -> Int64 {
50
+ guard index >= 0 && index < rows.count else { return 0 }
51
+ return rows[index][column] as? Int64 ?? 0
52
+ }
53
+
54
+ @objc public func double(forColumn column: String) -> Double {
55
+ guard index >= 0 && index < rows.count else { return 0 }
56
+ return rows[index][column] as? Double ?? 0
57
+ }
58
+
59
+ @objc public func bool(forColumn column: String) -> Bool {
60
+ guard index >= 0 && index < rows.count else { return false }
61
+ return rows[index][column] as? Bool ?? false
62
+ }
63
+
64
+ @objc public func data(forColumn column: String) -> Data? {
65
+ guard index >= 0 && index < rows.count else { return nil }
66
+ return rows[index][column] as? Data
67
+ }
68
+
69
+ @objc public func date(forColumn column: String) -> Date? {
70
+ guard index >= 0 && index < rows.count else { return nil }
71
+ if let d = rows[index][column] as? Date { return d }
72
+ if let ti = rows[index][column] as? Double { return Date(timeIntervalSince1970: ti) }
73
+ return nil
74
+ }
75
+
76
+ @objc public func object(forColumn column: String) -> Any? {
77
+ guard index >= 0 && index < rows.count else { return nil }
78
+ return rows[index][column]
79
+ }
80
+
81
+ @objc public func resultDictionary() -> [String: Any]? {
82
+ guard index >= 0 && index < rows.count else { return nil }
83
+ return rows[index]
84
+ }
85
+
86
+ // MARK: - Integer column index variants
87
+
88
+ private func columnName(at idx: Int) -> String? {
89
+ guard idx >= 0 && idx < columnNames.count else { return nil }
90
+ return columnNames[idx]
91
+ }
92
+
93
+ public func string(forColumn idx: Int) -> String? {
94
+ guard index >= 0 && index < rows.count else { return nil }
95
+ let row = rows[index]
96
+ let col = columnName(at: idx) ?? row.keys.sorted()[safe: idx]
97
+ guard let col = col else { return nil }
98
+ return row[col] as? String
99
+ }
100
+
101
+ public func int(forColumn idx: Int) -> Int32 {
102
+ guard index >= 0 && index < rows.count else { return 0 }
103
+ let row = rows[index]
104
+ let col = columnName(at: idx) ?? row.keys.sorted()[safe: idx]
105
+ guard let col = col else { return 0 }
106
+ return row[col] as? Int32 ?? Int32(row[col] as? Int ?? 0)
107
+ }
108
+
109
+ public func long(forColumn idx: Int) -> Int64 {
110
+ guard index >= 0 && index < rows.count else { return 0 }
111
+ let row = rows[index]
112
+ let col = columnName(at: idx) ?? row.keys.sorted()[safe: idx]
113
+ guard let col = col else { return 0 }
114
+ return row[col] as? Int64 ?? Int64(row[col] as? Int ?? 0)
115
+ }
116
+
117
+ public func double(forColumn idx: Int) -> Double {
118
+ guard index >= 0 && index < rows.count else { return 0 }
119
+ let row = rows[index]
120
+ let col = columnName(at: idx) ?? row.keys.sorted()[safe: idx]
121
+ guard let col = col else { return 0 }
122
+ return row[col] as? Double ?? 0
123
+ }
124
+
125
+ public func bool(forColumn idx: Int) -> Bool {
126
+ guard index >= 0 && index < rows.count else { return false }
127
+ let row = rows[index]
128
+ let col = columnName(at: idx) ?? row.keys.sorted()[safe: idx]
129
+ guard let col = col else { return false }
130
+ return row[col] as? Bool ?? false
131
+ }
132
+
133
+ public func data(forColumn idx: Int) -> Data? {
134
+ guard index >= 0 && index < rows.count else { return nil }
135
+ let row = rows[index]
136
+ let col = columnName(at: idx) ?? row.keys.sorted()[safe: idx]
137
+ guard let col = col else { return nil }
138
+ return row[col] as? Data
139
+ }
140
+
141
+ public func date(forColumn idx: Int) -> Date? {
142
+ guard index >= 0 && index < rows.count else { return nil }
143
+ let row = rows[index]
144
+ let col = columnName(at: idx) ?? row.keys.sorted()[safe: idx]
145
+ guard let col = col else { return nil }
146
+ if let d = row[col] as? Date { return d }
147
+ if let ti = row[col] as? Double { return Date(timeIntervalSince1970: ti) }
148
+ return nil
149
+ }
150
+ }
151
+
152
+ private extension Array {
153
+ subscript(safe idx: Int) -> Element? {
154
+ guard idx >= 0 && idx < count else { return nil }
155
+ return self[idx]
156
+ }
157
+ }