@josuelmm/capacitor-background-geolocation 1.0.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 (207) hide show
  1. package/JosuelmmCapacitorBackgroundGeolocation.podspec +34 -0
  2. package/LICENSE +17 -0
  3. package/NOTICE.md +32 -0
  4. package/Package.swift +45 -0
  5. package/README.md +402 -0
  6. package/android/build.gradle +79 -0
  7. package/android/proguard-rules.pro +1 -0
  8. package/android/src/main/AndroidManifest.xml +83 -0
  9. package/android/src/main/java/com/evgenii/jsevaluator/HandlerWrapper.java +18 -0
  10. package/android/src/main/java/com/evgenii/jsevaluator/JavaScriptInterface.java +22 -0
  11. package/android/src/main/java/com/evgenii/jsevaluator/JsEvaluator.java +133 -0
  12. package/android/src/main/java/com/evgenii/jsevaluator/JsFunctionCallFormatter.java +37 -0
  13. package/android/src/main/java/com/evgenii/jsevaluator/WebViewWrapper.java +71 -0
  14. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/CallJavaResultInterface.java +8 -0
  15. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/HandlerWrapperInterface.java +5 -0
  16. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/JsCallback.java +10 -0
  17. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/JsEvaluatorInterface.java +18 -0
  18. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/WebViewWrapperInterface.java +14 -0
  19. package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/BackgroundGeolocationPlugin.java +898 -0
  20. package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/ConfigMapper.java +303 -0
  21. package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/HeadlessTaskRegistry.java +34 -0
  22. package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/JsEvaluatorTaskRunner.java +63 -0
  23. package/android/src/main/java/com/marianhello/bgloc/BackgroundGeolocationFacade.java +699 -0
  24. package/android/src/main/java/com/marianhello/bgloc/BootCompletedReceiver.java +103 -0
  25. package/android/src/main/java/com/marianhello/bgloc/Config.java +1155 -0
  26. package/android/src/main/java/com/marianhello/bgloc/ConnectivityListener.java +5 -0
  27. package/android/src/main/java/com/marianhello/bgloc/HttpPostService.java +362 -0
  28. package/android/src/main/java/com/marianhello/bgloc/LocationManager.java +138 -0
  29. package/android/src/main/java/com/marianhello/bgloc/PluginDelegate.java +45 -0
  30. package/android/src/main/java/com/marianhello/bgloc/PluginException.java +38 -0
  31. package/android/src/main/java/com/marianhello/bgloc/PostLocationTask.java +238 -0
  32. package/android/src/main/java/com/marianhello/bgloc/ResourceResolver.java +55 -0
  33. package/android/src/main/java/com/marianhello/bgloc/data/AbstractLocationTemplate.java +69 -0
  34. package/android/src/main/java/com/marianhello/bgloc/data/ArrayListLocationTemplate.java +88 -0
  35. package/android/src/main/java/com/marianhello/bgloc/data/BackgroundActivity.java +108 -0
  36. package/android/src/main/java/com/marianhello/bgloc/data/BackgroundLocation.java +1088 -0
  37. package/android/src/main/java/com/marianhello/bgloc/data/ConfigJsonMapper.java +211 -0
  38. package/android/src/main/java/com/marianhello/bgloc/data/ConfigurationDAO.java +13 -0
  39. package/android/src/main/java/com/marianhello/bgloc/data/DAOFactory.java +17 -0
  40. package/android/src/main/java/com/marianhello/bgloc/data/HashMapLocationTemplate.java +82 -0
  41. package/android/src/main/java/com/marianhello/bgloc/data/LocationDAO.java +27 -0
  42. package/android/src/main/java/com/marianhello/bgloc/data/LocationTemplate.java +12 -0
  43. package/android/src/main/java/com/marianhello/bgloc/data/LocationTemplateFactory.java +71 -0
  44. package/android/src/main/java/com/marianhello/bgloc/data/LocationTransform.java +19 -0
  45. package/android/src/main/java/com/marianhello/bgloc/data/SessionLocationDAO.java +18 -0
  46. package/android/src/main/java/com/marianhello/bgloc/data/provider/ContentProviderLocationDAO.java +406 -0
  47. package/android/src/main/java/com/marianhello/bgloc/data/provider/LocationContentProvider.java +321 -0
  48. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteConfigurationContract.java +94 -0
  49. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteConfigurationDAO.java +227 -0
  50. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteLocationContract.java +122 -0
  51. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteLocationDAO.java +550 -0
  52. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteOpenHelper.java +189 -0
  53. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteSessionContract.java +74 -0
  54. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteSessionLocationDAO.java +169 -0
  55. package/android/src/main/java/com/marianhello/bgloc/driving/DrivingEventsDetector.java +265 -0
  56. package/android/src/main/java/com/marianhello/bgloc/headless/AbstractTaskRunner.java +15 -0
  57. package/android/src/main/java/com/marianhello/bgloc/headless/ActivityTask.java +48 -0
  58. package/android/src/main/java/com/marianhello/bgloc/headless/JsCallback.java +10 -0
  59. package/android/src/main/java/com/marianhello/bgloc/headless/LocationTask.java +60 -0
  60. package/android/src/main/java/com/marianhello/bgloc/headless/StationaryTask.java +25 -0
  61. package/android/src/main/java/com/marianhello/bgloc/headless/Task.java +8 -0
  62. package/android/src/main/java/com/marianhello/bgloc/headless/TaskRunner.java +5 -0
  63. package/android/src/main/java/com/marianhello/bgloc/headless/TaskRunnerFactory.java +8 -0
  64. package/android/src/main/java/com/marianhello/bgloc/http/UrlTemplateResolver.java +115 -0
  65. package/android/src/main/java/com/marianhello/bgloc/oem/BatteryOemHelper.java +214 -0
  66. package/android/src/main/java/com/marianhello/bgloc/provider/AbstractLocationProvider.java +218 -0
  67. package/android/src/main/java/com/marianhello/bgloc/provider/ActivityRecognitionLocationProvider.java +385 -0
  68. package/android/src/main/java/com/marianhello/bgloc/provider/DistanceFilterLocationProvider.java +685 -0
  69. package/android/src/main/java/com/marianhello/bgloc/provider/LocationProvider.java +32 -0
  70. package/android/src/main/java/com/marianhello/bgloc/provider/LocationProviderFactory.java +47 -0
  71. package/android/src/main/java/com/marianhello/bgloc/provider/ProviderDelegate.java +12 -0
  72. package/android/src/main/java/com/marianhello/bgloc/provider/RawLocationProvider.java +175 -0
  73. package/android/src/main/java/com/marianhello/bgloc/sensor/SensorFusionDetector.java +199 -0
  74. package/android/src/main/java/com/marianhello/bgloc/service/LocationService.java +16 -0
  75. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceImpl.java +1531 -0
  76. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceInfo.java +6 -0
  77. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceInfoImpl.java +41 -0
  78. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceIntentBuilder.java +203 -0
  79. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceProxy.java +156 -0
  80. package/android/src/main/java/com/marianhello/bgloc/sync/AccountHelper.java +39 -0
  81. package/android/src/main/java/com/marianhello/bgloc/sync/Authenticator.java +68 -0
  82. package/android/src/main/java/com/marianhello/bgloc/sync/AuthenticatorService.java +28 -0
  83. package/android/src/main/java/com/marianhello/bgloc/sync/BatchManager.java +311 -0
  84. package/android/src/main/java/com/marianhello/bgloc/sync/NotificationHelper.java +148 -0
  85. package/android/src/main/java/com/marianhello/bgloc/sync/SyncAdapter.java +301 -0
  86. package/android/src/main/java/com/marianhello/bgloc/sync/SyncService.java +68 -0
  87. package/android/src/main/java/com/marianhello/logging/DBLogReader.java +208 -0
  88. package/android/src/main/java/com/marianhello/logging/LogEntry.java +99 -0
  89. package/android/src/main/java/com/marianhello/logging/LoggerManager.java +70 -0
  90. package/android/src/main/java/com/marianhello/logging/UncaughtExceptionLogger.java +36 -0
  91. package/android/src/main/java/com/marianhello/utils/CloneHelper.java +22 -0
  92. package/android/src/main/java/com/marianhello/utils/Convert.java +56 -0
  93. package/android/src/main/java/com/marianhello/utils/TextUtils.java +72 -0
  94. package/android/src/main/java/com/marianhello/utils/ToneGenerator.java +68 -0
  95. package/android/src/main/java/org/apache/commons/io/Charsets.java +153 -0
  96. package/android/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java +344 -0
  97. package/android/src/main/java/org/chromium/content/browser/ThreadUtils.java +134 -0
  98. package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlExpression.java +398 -0
  99. package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlSelectStatement.java +671 -0
  100. package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlStatement.java +29 -0
  101. package/android/src/main/java/ru/andremoniy/utils/TextUtils.java +61 -0
  102. package/android/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  103. package/android/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  104. package/android/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  105. package/android/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  106. package/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  107. package/android/src/main/res/values/strings.xml +15 -0
  108. package/android/src/main/res/xml/authenticator.xml +7 -0
  109. package/android/src/main/res/xml/syncadapter.xml +9 -0
  110. package/dist/esm/definitions.d.ts +1052 -0
  111. package/dist/esm/definitions.js +142 -0
  112. package/dist/esm/definitions.js.map +1 -0
  113. package/dist/esm/index.d.ts +8 -0
  114. package/dist/esm/index.js +23 -0
  115. package/dist/esm/index.js.map +1 -0
  116. package/dist/esm/web.d.ts +92 -0
  117. package/dist/esm/web.js +242 -0
  118. package/dist/esm/web.js.map +1 -0
  119. package/dist/plugin.cjs.js +415 -0
  120. package/dist/plugin.cjs.js.map +1 -0
  121. package/dist/plugin.js +418 -0
  122. package/dist/plugin.js.map +1 -0
  123. package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin-Bridging-Header.h +18 -0
  124. package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin.m +52 -0
  125. package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin.swift +750 -0
  126. package/ios/Tests/BackgroundGeolocationPluginTests/BackgroundGeolocationPluginTests.swift +12 -0
  127. package/ios/common/BackgroundGeolocation/CocoaLumberjack.h +1945 -0
  128. package/ios/common/BackgroundGeolocation/CocoaLumberjack.m +5255 -0
  129. package/ios/common/BackgroundGeolocation/FMDB.h +2357 -0
  130. package/ios/common/BackgroundGeolocation/FMDB.m +2672 -0
  131. package/ios/common/BackgroundGeolocation/FMDBLogger.h +42 -0
  132. package/ios/common/BackgroundGeolocation/FMDBLogger.m +264 -0
  133. package/ios/common/BackgroundGeolocation/INTULocationManager/INTUHeadingRequest.h +41 -0
  134. package/ios/common/BackgroundGeolocation/INTULocationManager/INTUHeadingRequest.m +68 -0
  135. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager+Internal.h +33 -0
  136. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager.h +178 -0
  137. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager.m +1025 -0
  138. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequest.h +103 -0
  139. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequest.m +238 -0
  140. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequestDefines.h +163 -0
  141. package/ios/common/BackgroundGeolocation/INTULocationManager/INTURequestIDGenerator.h +39 -0
  142. package/ios/common/BackgroundGeolocation/INTULocationManager/INTURequestIDGenerator.m +37 -0
  143. package/ios/common/BackgroundGeolocation/MAURAbstractLocationProvider.h +51 -0
  144. package/ios/common/BackgroundGeolocation/MAURAbstractLocationProvider.m +53 -0
  145. package/ios/common/BackgroundGeolocation/MAURActivity.h +23 -0
  146. package/ios/common/BackgroundGeolocation/MAURActivity.m +52 -0
  147. package/ios/common/BackgroundGeolocation/MAURActivityLocationProvider.h +18 -0
  148. package/ios/common/BackgroundGeolocation/MAURActivityLocationProvider.m +340 -0
  149. package/ios/common/BackgroundGeolocation/MAURBackgroundGeolocationFacade.h +88 -0
  150. package/ios/common/BackgroundGeolocation/MAURBackgroundGeolocationFacade.m +1193 -0
  151. package/ios/common/BackgroundGeolocation/MAURBackgroundSync.h +46 -0
  152. package/ios/common/BackgroundGeolocation/MAURBackgroundSync.m +283 -0
  153. package/ios/common/BackgroundGeolocation/MAURBackgroundTaskManager.h +25 -0
  154. package/ios/common/BackgroundGeolocation/MAURBackgroundTaskManager.m +105 -0
  155. package/ios/common/BackgroundGeolocation/MAURConfig.h +99 -0
  156. package/ios/common/BackgroundGeolocation/MAURConfig.m +636 -0
  157. package/ios/common/BackgroundGeolocation/MAURConfigurationContract.h +53 -0
  158. package/ios/common/BackgroundGeolocation/MAURConfigurationContract.m +54 -0
  159. package/ios/common/BackgroundGeolocation/MAURDistanceFilterLocationProvider.h +20 -0
  160. package/ios/common/BackgroundGeolocation/MAURDistanceFilterLocationProvider.m +550 -0
  161. package/ios/common/BackgroundGeolocation/MAURGeolocationOpenHelper.h +17 -0
  162. package/ios/common/BackgroundGeolocation/MAURGeolocationOpenHelper.m +124 -0
  163. package/ios/common/BackgroundGeolocation/MAURLocation.h +73 -0
  164. package/ios/common/BackgroundGeolocation/MAURLocation.m +392 -0
  165. package/ios/common/BackgroundGeolocation/MAURLocationContract.h +38 -0
  166. package/ios/common/BackgroundGeolocation/MAURLocationContract.m +39 -0
  167. package/ios/common/BackgroundGeolocation/MAURLocationManager.h +53 -0
  168. package/ios/common/BackgroundGeolocation/MAURLocationManager.m +305 -0
  169. package/ios/common/BackgroundGeolocation/MAURLogReader.h +26 -0
  170. package/ios/common/BackgroundGeolocation/MAURLogReader.m +122 -0
  171. package/ios/common/BackgroundGeolocation/MAURLogging.h +19 -0
  172. package/ios/common/BackgroundGeolocation/MAURPostLocationTask.h +53 -0
  173. package/ios/common/BackgroundGeolocation/MAURPostLocationTask.m +367 -0
  174. package/ios/common/BackgroundGeolocation/MAURProviderDelegate.h +52 -0
  175. package/ios/common/BackgroundGeolocation/MAURRawLocationProvider.h +18 -0
  176. package/ios/common/BackgroundGeolocation/MAURRawLocationProvider.m +138 -0
  177. package/ios/common/BackgroundGeolocation/MAURSQLiteConfigurationDAO.h +26 -0
  178. package/ios/common/BackgroundGeolocation/MAURSQLiteConfigurationDAO.m +335 -0
  179. package/ios/common/BackgroundGeolocation/MAURSQLiteHelper.h +57 -0
  180. package/ios/common/BackgroundGeolocation/MAURSQLiteHelper.m +93 -0
  181. package/ios/common/BackgroundGeolocation/MAURSQLiteLocationDAO.h +52 -0
  182. package/ios/common/BackgroundGeolocation/MAURSQLiteLocationDAO.m +520 -0
  183. package/ios/common/BackgroundGeolocation/MAURSQLiteOpenHelper.h +32 -0
  184. package/ios/common/BackgroundGeolocation/MAURSQLiteOpenHelper.m +276 -0
  185. package/ios/common/BackgroundGeolocation/MAURSensorFusionDetector.h +41 -0
  186. package/ios/common/BackgroundGeolocation/MAURSensorFusionDetector.m +137 -0
  187. package/ios/common/BackgroundGeolocation/MAURSessionLocationContract.h +29 -0
  188. package/ios/common/BackgroundGeolocation/MAURSessionLocationContract.m +31 -0
  189. package/ios/common/BackgroundGeolocation/MAURSessionLocationDAO.h +25 -0
  190. package/ios/common/BackgroundGeolocation/MAURSessionLocationDAO.m +153 -0
  191. package/ios/common/BackgroundGeolocation/MAURUncaughtExceptionLogger.h +20 -0
  192. package/ios/common/BackgroundGeolocation/MAURUncaughtExceptionLogger.m +62 -0
  193. package/ios/common/BackgroundGeolocation/MAURUrlTemplateResolver.h +31 -0
  194. package/ios/common/BackgroundGeolocation/MAURUrlTemplateResolver.m +107 -0
  195. package/ios/common/BackgroundGeolocation/Reachability.h +102 -0
  196. package/ios/common/BackgroundGeolocation/Reachability.m +475 -0
  197. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/README.md +170 -0
  198. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/ext/NSString+ZIMString.h +55 -0
  199. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/ext/NSString+ZIMString.m +47 -0
  200. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlDataManipulationCommand.h +27 -0
  201. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlExpression.h +250 -0
  202. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlExpression.m +259 -0
  203. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlSelectStatement.h +360 -0
  204. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlSelectStatement.m +427 -0
  205. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlStatement.h +37 -0
  206. package/ios/common/BackgroundGeolocation/module.modulemap +16 -0
  207. package/package.json +82 -0
@@ -0,0 +1,367 @@
1
+ //
2
+ // MAURPostLocationTask.m
3
+ // BackgroundGeolocation
4
+ //
5
+ // Created by Marian Hello on 27/04/2018.
6
+ // Copyright © 2018 mauron85. All rights reserved.
7
+ //
8
+
9
+ #import <Foundation/Foundation.h>
10
+ #import "Reachability.h"
11
+ #import "MAURSQLiteLocationDAO.h"
12
+ #import "MAURBackgroundSync.h"
13
+ #import "MAURConfig.h"
14
+ #import "MAURLogging.h"
15
+ #import "MAURPostLocationTask.h"
16
+ #import "MAURSQLiteLocationDAO.h"
17
+ #import "MAURSessionLocationDAO.h"
18
+ #import "MAURUrlTemplateResolver.h"
19
+
20
+ static NSString * const TAG = @"MAURPostLocationTask";
21
+
22
+ @interface MAURPostLocationTask() <MAURBackgroundSyncDelegate>
23
+ {
24
+
25
+ }
26
+ @end
27
+
28
+ @implementation MAURPostLocationTask
29
+ {
30
+ Reachability *reach;
31
+ MAURBackgroundSync *uploader;
32
+ BOOL hasConnectivity;
33
+ }
34
+
35
+ static MAURLocationTransform s_locationTransform = nil;
36
+
37
+ - (instancetype) init
38
+ {
39
+ self = [super init];
40
+
41
+ if (self == nil) {
42
+ return self;
43
+ }
44
+
45
+ hasConnectivity = YES;
46
+
47
+ uploader = [[MAURBackgroundSync alloc] init];
48
+ uploader.delegate = self;
49
+
50
+ reach = [Reachability reachabilityWithHostname:@"www.google.com"];
51
+ reach.reachableBlock = ^(Reachability *_reach) {
52
+ // keep in mind this is called on a background thread
53
+ // and if you are updating the UI it needs to happen
54
+ // on the main thread:
55
+ hasConnectivity = YES;
56
+ [_reach stopNotifier];
57
+ };
58
+
59
+ reach.unreachableBlock = ^(Reachability *reach) {
60
+ hasConnectivity = NO;
61
+ };
62
+
63
+ return self;
64
+ }
65
+
66
+ - (void) start
67
+ {
68
+ hasConnectivity = YES;
69
+ [reach startNotifier];
70
+ }
71
+
72
+ - (void) stop
73
+ {
74
+ [reach stopNotifier];
75
+ }
76
+
77
+ - (void) add:(MAURLocation * _Nonnull)inLocation
78
+ {
79
+ // Take this variable on the main thread to be safe
80
+ MAURLocationTransform locationTransform = s_locationTransform;
81
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
82
+
83
+ MAURLocation *location = inLocation;
84
+
85
+ if (locationTransform != nil) {
86
+ // v4.5.1 — snapshot v4.3+ fields BEFORE transform so they survive a transform
87
+ // that returns a brand new MAURLocation instance (otherwise events/battery would
88
+ // be lost en route to SQLite / backend).
89
+ NSMutableArray *rawEvents = inLocation.drivingEvents;
90
+ NSNumber *rawBattery = inLocation.batteryLevel;
91
+ NSNumber *rawCharging = inLocation.isCharging;
92
+
93
+ location = locationTransform(location);
94
+
95
+ if (location == nil) {
96
+ return;
97
+ }
98
+
99
+ // v4.5.1 — re-attach fields the transform may have dropped. When the transform
100
+ // produced a NEW instance (`location != inLocation`), MERGE rawEvents into the new
101
+ // instance's array instead of overwriting — same semantics as Android
102
+ // `LocationServiceImpl.onLocation` re-attach. If the transform returned the same
103
+ // instance (mutated in place) the rawEvents are already there.
104
+ if (location != inLocation) {
105
+ if (rawEvents != nil && [rawEvents count] > 0) {
106
+ if (location.drivingEvents == nil) {
107
+ location.drivingEvents = [rawEvents mutableCopy];
108
+ } else {
109
+ [location.drivingEvents addObjectsFromArray:rawEvents];
110
+ }
111
+ }
112
+ if (location.batteryLevel == nil) location.batteryLevel = rawBattery;
113
+ if (location.isCharging == nil) location.isCharging = rawCharging;
114
+ }
115
+ }
116
+
117
+ // v4.5.1 — drain pending driving events ONTO the post-transform location. Previously
118
+ // the facade drained them BEFORE [postLocationTask add:], so a transform that returned
119
+ // nil silently lost every buffered event. Now: if transform succeeded we're guaranteed
120
+ // `location != nil` here and the buffer is drained safely.
121
+ NSMutableArray *pendingBuffer = self.pendingDrivingEventsBuffer;
122
+ if (pendingBuffer != nil) {
123
+ @synchronized (pendingBuffer) {
124
+ if ([pendingBuffer count] > 0) {
125
+ NSTimeInterval nowMs = [[NSDate date] timeIntervalSince1970] * 1000.0;
126
+ if (location.drivingEvents == nil) location.drivingEvents = [NSMutableArray array];
127
+ for (NSDictionary *ev in pendingBuffer) {
128
+ NSNumber *t = ev[@"time"];
129
+ NSTimeInterval evMs = t != nil ? [t doubleValue] : nowMs;
130
+ if (nowMs - evMs <= 60000.0) {
131
+ [location.drivingEvents addObject:ev];
132
+ }
133
+ }
134
+ [pendingBuffer removeAllObjects];
135
+ }
136
+ }
137
+ }
138
+ // v4.5.1 — stamp battery snapshot AFTER transform so it lands on the POSTed instance
139
+ // even if the transform created a new one.
140
+ void (^attachBattery)(MAURLocation *) = self.attachBatterySnapshot;
141
+ if (attachBattery != nil) {
142
+ attachBattery(location);
143
+ }
144
+
145
+ // v3.5 Phase 4: mock location policy. Detection already exists in MAURLocation.simulated.
146
+ if (location.simulated != nil && [location.simulated boolValue]) {
147
+ NSString *policy = self.config.mockLocationPolicy ?: @"allow";
148
+ if ([@"drop" isEqualToString:policy]) {
149
+ DDLogInfo(@"%@ Simulated/mock location dropped (mockLocationPolicy=drop)", TAG);
150
+ return;
151
+ }
152
+ // "flag": leave it. The simulated NSNumber is already on the model and propagates via toResultFromTemplate.
153
+ // "allow": no-op.
154
+ }
155
+
156
+ MAURSQLiteLocationDAO *locationDAO = [MAURSQLiteLocationDAO sharedInstance];
157
+ // TODO: investigate location id always 0
158
+ NSNumber *locationId = [locationDAO persistLocation:location limitRows:self.config.maxLocations.integerValue];
159
+
160
+ if ([[MAURSessionLocationDAO sharedInstance] isSessionActive]) {
161
+ [[MAURSessionLocationDAO sharedInstance] persistSessionLocation:location];
162
+ }
163
+
164
+ if (hasConnectivity && [self.config hasValidUrl]) {
165
+ NSError *error = nil;
166
+ if ([self post:location toUrl:self.config.url withTemplate:self.config._template withHttpHeaders:self.config.httpHeaders error:&error]) {
167
+ if (locationId != nil) {
168
+ [locationDAO deleteLocation:locationId error:nil];
169
+ }
170
+ }
171
+ }
172
+
173
+ if ([self.config hasValidSyncUrl] && [self.config syncEnabled]) {
174
+ NSNumber *locationsCount = [locationDAO getLocationsForSyncCount];
175
+ NSInteger threshold = self.config.syncThreshold != nil ? self.config.syncThreshold.integerValue : 100;
176
+ if (locationsCount && [locationsCount integerValue] >= threshold) {
177
+ DDLogDebug(@"%@ Attempt to sync locations: %@ threshold: %ld", TAG, locationsCount, (long)threshold);
178
+ [self sync];
179
+ }
180
+ }
181
+ });
182
+ }
183
+
184
+ - (BOOL) post:(MAURLocation*)location
185
+ toUrl:(NSString*)url
186
+ withTemplate:(id)locationTemplate
187
+ withHttpHeaders:(NSMutableDictionary*)httpHeaders
188
+ error:(NSError * __autoreleasing *)outError
189
+ {
190
+ // v3.3 Phase 2: backend-agnostic transport.
191
+ // Resolve URL template using current location + queryParams (for both single and batch modes).
192
+ NSString *resolvedUrl = [MAURUrlTemplateResolver resolve:url location:location queryParams:self.config.queryParams];
193
+
194
+ NSString *method = self.config.httpMethod ?: @"POST";
195
+ NSString *mode = self.config.httpMode ?: @"batch";
196
+ BOOL isBodyless = [@"GET" isEqualToString:method];
197
+ BOOL singleMode = isBodyless || [@"single" isEqualToString:mode];
198
+
199
+ NSData *data = nil;
200
+ if (!isBodyless) {
201
+ // For single mode (or body methods that prefer one location per request) send a JSONObject;
202
+ // for batch send the array (current behaviour).
203
+ if (singleMode) {
204
+ data = [NSJSONSerialization dataWithJSONObject:[location toResultFromTemplate:locationTemplate] options:0 error:outError];
205
+ } else {
206
+ NSArray *locations = [[NSArray alloc] initWithObjects:[location toResultFromTemplate:locationTemplate], nil];
207
+ data = [NSJSONSerialization dataWithJSONObject:locations options:0 error:outError];
208
+ }
209
+ if (!data) {
210
+ return NO;
211
+ }
212
+ }
213
+
214
+ NSString *jsonStr = data ? [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] : nil;
215
+ NSString *contentType = [httpHeaders objectForKey:@"Content-Type"];
216
+ if (!contentType) {
217
+ contentType = @"application/json";
218
+ }
219
+
220
+ NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:resolvedUrl]];
221
+ [request setHTTPMethod:method];
222
+ if (!isBodyless) {
223
+ [request setValue:contentType forHTTPHeaderField:@"Content-Type"];
224
+ }
225
+ if (httpHeaders != nil) {
226
+ for (id key in httpHeaders) {
227
+ if (![key isEqualToString:@"Content-Type"]) {
228
+ NSString *value = [httpHeaders objectForKey:key];
229
+ [request addValue:value forHTTPHeaderField:key];
230
+ }
231
+ }
232
+ }
233
+
234
+ if (!isBodyless) {
235
+ if ([contentType isEqualToString:@"application/x-www-form-urlencoded"]) {
236
+ id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:outError];
237
+ NSDictionary *dict = nil;
238
+ if ([jsonObject isKindOfClass:[NSArray class]] && [jsonObject count] == 1) {
239
+ dict = [jsonObject firstObject];
240
+ } else if ([jsonObject isKindOfClass:[NSDictionary class]]) {
241
+ dict = jsonObject;
242
+ }
243
+ if (dict) {
244
+ NSMutableArray *parts = [NSMutableArray array];
245
+ for (NSString *key in dict) {
246
+ NSString *value = [NSString stringWithFormat:@"%@", dict[key]];
247
+ NSString *encodedKey = [key stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
248
+ NSString *encodedValue = [value stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
249
+ NSString *part = [NSString stringWithFormat:@"%@=%@", encodedKey, encodedValue];
250
+ [parts addObject:part];
251
+ }
252
+ NSString *encodedString = [parts componentsJoinedByString:@"&"];
253
+ [request setHTTPBody:[encodedString dataUsingEncoding:NSUTF8StringEncoding]];
254
+ } else {
255
+ [request setHTTPBody:[jsonStr dataUsingEncoding:NSUTF8StringEncoding]];
256
+ }
257
+ } else {
258
+ [request setHTTPBody:[jsonStr dataUsingEncoding:NSUTF8StringEncoding]];
259
+ }
260
+ }
261
+
262
+ // v3.4: NSURLSession (iOS 7+) replaces deprecated [NSURLConnection sendSynchronousRequest:].
263
+ // We run on a background queue (see -add: dispatch_async) so a semaphore-based wait is safe.
264
+ __block NSHTTPURLResponse *urlResponse = nil;
265
+ __block NSError *taskError = nil;
266
+ dispatch_semaphore_t sema = dispatch_semaphore_create(0);
267
+ NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession]
268
+ dataTaskWithRequest:request
269
+ completionHandler:^(NSData * _Nullable d, NSURLResponse * _Nullable response, NSError * _Nullable err) {
270
+ urlResponse = (NSHTTPURLResponse *)response;
271
+ taskError = err;
272
+ dispatch_semaphore_signal(sema);
273
+ }];
274
+ [dataTask resume];
275
+ // 120s ceiling to mirror the previous synchronous timeout; URLSession also enforces its own.
276
+ dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(120 * NSEC_PER_SEC)));
277
+ if (taskError != nil && outError != NULL) {
278
+ *outError = taskError;
279
+ }
280
+
281
+ NSInteger statusCode = urlResponse.statusCode;
282
+
283
+ if (statusCode == 285)
284
+ {
285
+ // Okay, but we don't need to continue sending these
286
+ DDLogDebug(@"Location was sent to the server, and received an \"HTTP 285 Updated Not Required\"");
287
+ dispatch_async(dispatch_get_main_queue(), ^{
288
+ if (_delegate && [_delegate respondsToSelector:@selector(postLocationTaskRequestedAbortUpdates:)])
289
+ {
290
+ [_delegate postLocationTaskRequestedAbortUpdates:self];
291
+ }
292
+ });
293
+ }
294
+
295
+ if (statusCode == 401)
296
+ {
297
+ dispatch_async(dispatch_get_main_queue(), ^{
298
+ if (_delegate && [_delegate respondsToSelector:@selector(postLocationTaskHttpAuthorizationUpdates:)])
299
+ {
300
+ [_delegate postLocationTaskHttpAuthorizationUpdates:self];
301
+ }
302
+ });
303
+ }
304
+ // All 2xx statuses are okay
305
+ if (statusCode >= 200 && statusCode < 300)
306
+ {
307
+ return YES;
308
+ }
309
+
310
+ // v4.4.1: guard against outError == NULL (defensive — current callers pass &error).
311
+ if (outError == NULL || *outError == nil) {
312
+ DDLogDebug(@"%@ Server error while posting locations responseCode: %ld", TAG, (long)statusCode);
313
+ } else {
314
+ DDLogError(@"%@ Error while posting locations %@", TAG, [*outError localizedDescription]);
315
+ }
316
+
317
+ return NO;
318
+ }
319
+
320
+ - (void) sync
321
+ {
322
+ if (![self.config syncEnabled] || ![self.config hasValidSyncUrl]) {
323
+ return;
324
+ }
325
+ // v4.5.1 — rescue rows stuck in SyncPending from a previous upload that never completed
326
+ // (app/process killed mid-flight). Anything older than 15 min is safe to revert to
327
+ // PostPending; rows younger than that may still be uploading on a background NSURLSession.
328
+ NSTimeInterval staleCutoff = [[NSDate date] timeIntervalSince1970] - (15 * 60);
329
+ [[MAURSQLiteLocationDAO sharedInstance] restoreStaleSyncLocationsOlderThan:staleCutoff error:nil];
330
+ // For sync (batch) only static queryParams placeholders apply; per-location templating
331
+ // belongs in real-time post (httpMode="single" + httpMethod=GET) instead.
332
+ NSString *resolvedSyncUrl = [MAURUrlTemplateResolver resolve:self.config.syncUrl location:nil queryParams:self.config.queryParams];
333
+ NSString *syncMethod = self.config.syncHttpMethod ?: @"POST";
334
+ [uploader sync:resolvedSyncUrl withTemplate:self.config._template withHttpHeaders:self.config.httpHeaders withMethod:syncMethod];
335
+ }
336
+
337
+ #pragma mark - Location transform
338
+
339
+ + (void) setLocationTransform:(MAURLocationTransform _Nullable)transform
340
+ {
341
+ s_locationTransform = transform;
342
+ }
343
+
344
+ + (MAURLocationTransform _Nullable) locationTransform
345
+ {
346
+ return s_locationTransform;
347
+ }
348
+
349
+ #pragma mark - MAURBackgroundSyncDelegate
350
+
351
+ - (void)backgroundSyncRequestedAbortUpdates:(MAURBackgroundSync *)task
352
+ {
353
+ if (_delegate && [_delegate respondsToSelector:@selector(postLocationTaskRequestedAbortUpdates:)])
354
+ {
355
+ [_delegate postLocationTaskRequestedAbortUpdates:self];
356
+ }
357
+ }
358
+
359
+ - (void)backgroundSyncHttpAuthorizationUpdates:(MAURBackgroundSync *)task
360
+ {
361
+ if (_delegate && [_delegate respondsToSelector:@selector(postLocationTaskHttpAuthorizationUpdates:)])
362
+ {
363
+ [_delegate postLocationTaskHttpAuthorizationUpdates:self];
364
+ }
365
+ }
366
+
367
+ @end
@@ -0,0 +1,52 @@
1
+ //
2
+ // MAURProviderDelegate.h
3
+ // BackgroundGeolocation
4
+ //
5
+ // Created by Marian Hello on 14/09/2016.
6
+ // Copyright © 2016 mauron85. All rights reserved.
7
+ //
8
+
9
+ #ifndef MAURProviderDelegate_h
10
+ #define MAURProviderDelegate_h
11
+
12
+ #import "MAURLocation.h"
13
+ #import "MAURActivity.h"
14
+ //#import "MAURLocationController.h"
15
+
16
+ typedef NS_ENUM(NSInteger, MAURBGErrorCode) {
17
+ MAURBGPermissionDenied = 1000,
18
+ MAURBGSettingsError = 1001,
19
+ MAURBGConfigureError = 1002,
20
+ MAURBGServiceError = 1003,
21
+ MAURBGJsonError = 1004,
22
+ MAURBGNotImplemented = 9999
23
+ };
24
+
25
+ typedef NS_ENUM(NSInteger, MAURLocationAuthorizationStatus) {
26
+ MAURLocationAuthorizationDenied = 0,
27
+ MAURLocationAuthorizationAllowed = 1,
28
+ MAURLocationAuthorizationAlways = MAURLocationAuthorizationAllowed,
29
+ MAURLocationAuthorizationForeground = 2,
30
+ MAURLocationAuthorizationNotDetermined = 99,
31
+ };
32
+
33
+ typedef NS_ENUM(NSInteger, MAUROperationalMode) {
34
+ MAURBackgroundMode = 0,
35
+ MAURForegroundMode = 1
36
+ };
37
+
38
+ @protocol MAURProviderDelegate <NSObject>
39
+
40
+ - (void) onAuthorizationChanged:(MAURLocationAuthorizationStatus)authStatus;
41
+ - (void) onLocationChanged:(MAURLocation*)location;
42
+ - (void) onStationaryChanged:(MAURLocation*)location;
43
+ - (void) onLocationPause;
44
+ - (void) onLocationResume;
45
+ - (void) onActivityChanged:(MAURActivity*)activity;
46
+ - (void) onAbortRequested;
47
+ - (void) onHttpAuthorization;
48
+ - (void) onError:(NSError*)error;
49
+
50
+ @end
51
+
52
+ #endif /* MAURProviderDelegate_h */
@@ -0,0 +1,18 @@
1
+ //
2
+ // MAURRawLocationProvider.h
3
+ // BackgroundGeolocation
4
+ //
5
+ // Created by Marian Hello on 06/11/2017.
6
+ // Copyright © 2017 mauron85. All rights reserved.
7
+ //
8
+
9
+ #ifndef MAURRawLocationProvider_h
10
+ #define MAURRawLocationProvider_h
11
+
12
+ #import "MAURAbstractLocationProvider.h"
13
+
14
+ @interface MAURRawLocationProvider : MAURAbstractLocationProvider<MAURLocationProvider>
15
+
16
+ @end
17
+
18
+ #endif /* MAURRawLocationProvider_h */
@@ -0,0 +1,138 @@
1
+ //
2
+ // MAURRawLocationProvider.m
3
+ // BackgroundGeolocation
4
+ //
5
+ // Created by Marian Hello on 06/11/2017.
6
+ // Copyright © 2017 mauron85. All rights reserved.
7
+ //
8
+
9
+ #import <Foundation/Foundation.h>
10
+ #import "MAURRawLocationProvider.h"
11
+ #import "MAURLocationManager.h"
12
+ #import "MAURLogging.h"
13
+
14
+ static NSString * const TAG = @"RawLocationProvider";
15
+ static NSString * const Domain = @"com.marianhello";
16
+
17
+ @implementation MAURRawLocationProvider {
18
+
19
+ BOOL isStarted;
20
+ MAURLocationManager *locationManager;
21
+
22
+ MAURConfig *_config;
23
+ }
24
+
25
+ - (instancetype) init
26
+ {
27
+ self = [super init];
28
+
29
+ if (self) {
30
+ isStarted = NO;
31
+ }
32
+
33
+ return self;
34
+ }
35
+
36
+ - (void) onCreate {
37
+ locationManager = [MAURLocationManager sharedInstance];
38
+ locationManager.delegate = self;
39
+ }
40
+
41
+ - (BOOL) onConfigure:(MAURConfig*)config error:(NSError * __autoreleasing *)outError
42
+ {
43
+ DDLogVerbose(@"%@ configure", TAG);
44
+ _config = config;
45
+
46
+ locationManager.pausesLocationUpdatesAutomatically = [config pauseLocationUpdates];
47
+ locationManager.activityType = [config decodeActivityType];
48
+ locationManager.distanceFilter = config.distanceFilter.integerValue; // meters
49
+ locationManager.desiredAccuracy = [config decodeDesiredAccuracy];
50
+
51
+ return YES;
52
+ }
53
+
54
+ - (BOOL) onStart:(NSError * __autoreleasing *)outError
55
+ {
56
+ DDLogInfo(@"%@ will start", TAG);
57
+
58
+ if (!isStarted) {
59
+ [locationManager stopMonitoringSignificantLocationChanges];
60
+ isStarted = [locationManager start:outError];
61
+ }
62
+
63
+ return isStarted;
64
+ }
65
+
66
+ - (BOOL) onStop:(NSError * __autoreleasing *)outError
67
+ {
68
+ DDLogInfo(@"%@ will stop", TAG);
69
+
70
+ if (!isStarted) {
71
+ return YES;
72
+ }
73
+
74
+ [locationManager stopMonitoringSignificantLocationChanges];
75
+ if ([locationManager stop:outError]) {
76
+ isStarted = NO;
77
+ return YES;
78
+ }
79
+
80
+ return NO;
81
+ }
82
+
83
+ - (void) onTerminate
84
+ {
85
+ if (isStarted && !_config.stopOnTerminate) {
86
+ [locationManager startMonitoringSignificantLocationChanges];
87
+ }
88
+ }
89
+
90
+ - (void) onAuthorizationChanged:(MAURLocationAuthorizationStatus)authStatus
91
+ {
92
+ [self.delegate onAuthorizationChanged:authStatus];
93
+ }
94
+
95
+ - (void) onLocationsChanged:(NSArray*)locations
96
+ {
97
+ for (CLLocation *location in locations) {
98
+ MAURLocation *bgloc = [MAURLocation fromCLLocation:location];
99
+ [self.delegate onLocationChanged:bgloc];
100
+ }
101
+ }
102
+
103
+ - (void) onError:(NSError*)error
104
+ {
105
+ [self.delegate onError:error];
106
+ }
107
+
108
+ - (void) onPause:(CLLocationManager*)manager
109
+ {
110
+ [self.delegate onLocationPause];
111
+ }
112
+
113
+ - (void) onResume:(CLLocationManager*)manager
114
+ {
115
+ [self.delegate onLocationResume];
116
+ }
117
+
118
+ - (void) onDestroy {
119
+ DDLogInfo(@"Destroying %@ ", TAG);
120
+ [self onStop:nil];
121
+
122
+ // v4.5.2: MAURLocationManager is a singleton shared with the other providers.
123
+ // Release our delegate slot so a later provider swap does not leave this
124
+ // (already destroyed) instance as the active delegate.
125
+ if (locationManager != nil && locationManager.delegate == self) {
126
+ locationManager.delegate = nil;
127
+ }
128
+ }
129
+
130
+ - (void) dealloc
131
+ {
132
+ if (locationManager != nil && locationManager.delegate == self) {
133
+ locationManager.delegate = nil;
134
+ }
135
+ }
136
+
137
+ @end
138
+
@@ -0,0 +1,26 @@
1
+ //
2
+ // MAURSQLiteConfigurationDAO.h
3
+ // BackgroundGeolocation
4
+ //
5
+ // Created by Marian Hello on 01/12/2017.
6
+ // Copyright © 2017 mauron85. All rights reserved.
7
+ //
8
+
9
+ #ifndef MAURSQLiteConfigurationDAO_h
10
+ #define MAURSQLiteConfigurationDAO_h
11
+
12
+ #import "MAURConfig.h"
13
+
14
+ @interface MAURSQLiteConfigurationDAO : NSObject
15
+
16
+ + (instancetype) sharedInstance;
17
+ - (id) init NS_UNAVAILABLE;
18
+ - (BOOL) persistConfiguration:(MAURConfig*)config;
19
+ - (MAURConfig*) retrieveConfiguration;
20
+ - (BOOL) clearDatabase;
21
+ - (NSString*) getDatabaseName;
22
+ - (NSString*) getDatabasePath;
23
+
24
+ @end
25
+
26
+ #endif /* MAURSQLiteConfigurationDAO_h */