@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,46 @@
1
+ //
2
+ // MAURBackgroundSync.h
3
+ //
4
+ // Created by Marian Hello on 07/07/16.
5
+ // Copyright © 2016 mauron85. All rights reserved.
6
+ //
7
+
8
+ #ifndef MAURBackgroundSync_h
9
+ #define MAURBackgroundSync_h
10
+
11
+ #import <Foundation/Foundation.h>
12
+
13
+ @class MAURBackgroundSync;
14
+
15
+ // v3.5 Phase 4: notification names for sync events. The plugin layer observes them
16
+ // via NSNotificationCenter to forward into JS as syncStart / syncSuccess / syncError / syncProgress.
17
+ extern NSString * _Nonnull const MAURBackgroundSyncDidStartNotification;
18
+ extern NSString * _Nonnull const MAURBackgroundSyncDidSucceedNotification;
19
+ extern NSString * _Nonnull const MAURBackgroundSyncDidFailNotification;
20
+ extern NSString * _Nonnull const MAURBackgroundSyncDidProgressNotification;
21
+
22
+ @protocol MAURBackgroundSyncDelegate <NSObject>
23
+
24
+ @optional
25
+ - (void)backgroundSyncRequestedAbortUpdates:(MAURBackgroundSync * _Nonnull)task;
26
+ - (void)backgroundSyncHttpAuthorizationUpdates:(MAURBackgroundSync * _Nonnull)task;
27
+ // v3.5 Phase 4
28
+ - (void)backgroundSyncStarted:(MAURBackgroundSync * _Nonnull)task;
29
+ - (void)backgroundSyncSucceeded:(MAURBackgroundSync * _Nonnull)task locationsSent:(NSInteger)locationsSent;
30
+ - (void)backgroundSyncFailed:(MAURBackgroundSync * _Nonnull)task httpStatus:(NSInteger)httpStatus message:(NSString * _Nullable)message;
31
+
32
+ @end
33
+
34
+ @interface MAURBackgroundSync : NSObject
35
+
36
+ @property (nonatomic, weak) id<MAURBackgroundSyncDelegate> _Nullable delegate;
37
+
38
+ - (instancetype) init;
39
+ - (NSString*) status;
40
+ - (void) sync:(NSString * _Nonnull)url withTemplate:(id)locationTemplate withHttpHeaders:(NSMutableDictionary * _Nullable)httpHeaders;
41
+ - (void) sync:(NSString * _Nonnull)url withTemplate:(id)locationTemplate withHttpHeaders:(NSMutableDictionary * _Nullable)httpHeaders withMethod:(NSString * _Nullable)method;
42
+ - (void) cancel;
43
+
44
+ @end
45
+
46
+ #endif /* MAURBackgroundSync_h */
@@ -0,0 +1,283 @@
1
+ //
2
+ // MAURBackgroundSync.m
3
+ //
4
+ // Created by Marian Hello on 07/07/16.
5
+ // Copyright © 2016 mauron85. All rights reserved.
6
+ //
7
+
8
+ #import "UIKit/UIKit.h"
9
+ #import "MAURLogging.h"
10
+ #import "MAURBackgroundSync.h"
11
+ #import "MAURSQLiteLocationDAO.h"
12
+ #import <objc/runtime.h>
13
+
14
+ NSString * const MAURBackgroundSyncDidStartNotification = @"MAURBackgroundSyncDidStart";
15
+ NSString * const MAURBackgroundSyncDidSucceedNotification = @"MAURBackgroundSyncDidSucceed";
16
+ NSString * const MAURBackgroundSyncDidFailNotification = @"MAURBackgroundSyncDidFail";
17
+ NSString * const MAURBackgroundSyncDidProgressNotification = @"MAURBackgroundSyncDidProgress";
18
+
19
+ @interface MAURBackgroundSync () <NSURLSessionDelegate, NSURLSessionTaskDelegate>
20
+ {
21
+ NSURLSession *urlSession;
22
+ NSMutableArray *tasks;
23
+ }
24
+ @end
25
+
26
+ @implementation MAURBackgroundSync
27
+
28
+ - (instancetype) init
29
+ {
30
+ if(!(self = [super init])) return nil;
31
+
32
+ // v3.5 Phase 4: previously `tasks` was never allocated; addObject/removeObject/cancel/status
33
+ // silently no-op'd on nil. Allocate now so cancel and status actually work.
34
+ tasks = [[NSMutableArray alloc] init];
35
+
36
+ NSURLSessionConfiguration *conf = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.marianhello.session"];
37
+ conf.allowsCellularAccess = YES;
38
+ urlSession = [NSURLSession sessionWithConfiguration:conf delegate:self delegateQueue:[NSOperationQueue mainQueue]];
39
+
40
+ return self;
41
+ }
42
+
43
+ - (void)start
44
+ {
45
+ __block UIBackgroundTaskIdentifier bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
46
+ [[UIApplication sharedApplication] endBackgroundTask:bgTask];
47
+ }];
48
+
49
+ [urlSession getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
50
+ for(NSURLSessionUploadTask *task in uploadTasks) {
51
+ DDLogInfo(@"Restored upload task %zu for %@", (unsigned long)task.taskIdentifier, task.originalRequest.URL);
52
+ [tasks addObject:task];
53
+ [task resume];
54
+ }
55
+
56
+ [[UIApplication sharedApplication] endBackgroundTask:bgTask];
57
+ }];
58
+ }
59
+
60
+ - (void)cancel
61
+ {
62
+ for(NSURLSessionTask *task in tasks) {
63
+ [task cancel];
64
+ }
65
+ }
66
+
67
+ - (void) sync:(NSString * _Nonnull)url withTemplate:(id)locationTemplate withHttpHeaders:(NSMutableDictionary * _Nullable)httpHeaders
68
+ {
69
+ [self sync:url withTemplate:locationTemplate withHttpHeaders:httpHeaders withMethod:@"POST"];
70
+ }
71
+
72
+ - (void) sync:(NSString * _Nonnull)url withTemplate:(id)locationTemplate withHttpHeaders:(NSMutableDictionary * _Nullable)httpHeaders withMethod:(NSString * _Nullable)method
73
+ {
74
+ MAURSQLiteLocationDAO* locationDAO = [MAURSQLiteLocationDAO sharedInstance];
75
+ NSArray *locations = [locationDAO getLocationsForSync];
76
+
77
+ NSMutableArray *jsonArray = [[NSMutableArray alloc] initWithCapacity:[locations count]];
78
+ for (MAURLocation *location in locations) {
79
+ [jsonArray addObject:[location toResultFromTemplate:locationTemplate]];
80
+ }
81
+
82
+ NSError *error = nil;
83
+ NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonArray options:0 error:&error];
84
+
85
+ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
86
+ dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
87
+ dateFormatter.dateFormat = @"yyyyMMdd_HHmms";
88
+ dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
89
+ NSString *fileName = [NSString stringWithFormat:@"locations_%@.json", [dateFormatter stringFromDate:[NSDate date]]];
90
+ NSURL *jsonUrl = [NSURL fileURLWithPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:fileName]];
91
+ [jsonData writeToFile:jsonUrl.path atomically:NO];
92
+ uint64_t bytesTotalForThisFile = [[[NSFileManager defaultManager] attributesOfItemAtPath:jsonUrl.path error:nil] fileSize];
93
+
94
+ NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
95
+ NSString *resolvedMethod = (method != nil && method.length > 0) ? [method uppercaseString] : @"POST";
96
+ [request setHTTPMethod:resolvedMethod];
97
+ [request setTimeoutInterval:120]; // Prevents sync from hanging indefinitely if server does not respond
98
+ [request setValue:[NSString stringWithFormat:@"%llu", bytesTotalForThisFile] forHTTPHeaderField:@"Content-Length"];
99
+ [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
100
+
101
+ if (httpHeaders != nil) {
102
+ for(id key in httpHeaders) {
103
+ id value = [httpHeaders objectForKey:key];
104
+ [request addValue:value forHTTPHeaderField:key];
105
+ }
106
+ }
107
+ NSURLSessionTask *task = [urlSession uploadTaskWithRequest:request fromFile:jsonUrl];
108
+ task.taskDescription = fileName;
109
+ [tasks addObject:task];
110
+ DDLogInfo(@"Started upload for %@ as task %zu/%@/%@", jsonUrl.lastPathComponent, (unsigned long)task.taskIdentifier, task.taskDescription, task);
111
+
112
+ // v3.5 Phase 4: emit syncStart now that we are about to push to the server.
113
+ if (self.delegate && [self.delegate respondsToSelector:@selector(backgroundSyncStarted:)]) {
114
+ [self.delegate backgroundSyncStarted:self];
115
+ }
116
+ [[NSNotificationCenter defaultCenter] postNotificationName:MAURBackgroundSyncDidStartNotification object:self];
117
+
118
+ // Stash count so didCompleteWithError can report it as syncSuccess payload.
119
+ objc_setAssociatedObject(task, "locationsSent", @([jsonArray count]), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
120
+ // v4.5.1: capture cutoff timestamp NOW so on success we delete only the rows that existed
121
+ // before the upload started. Locations persisted DURING the upload are preserved.
122
+ objc_setAssociatedObject(task, "uploadCutoff",
123
+ @([[NSDate date] timeIntervalSince1970]), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
124
+
125
+ [task resume];
126
+
127
+ }
128
+
129
+ // http://stackoverflow.com/a/572623/48125
130
+ NSString *stringFromFileSize(unsigned long long theSize)
131
+ {
132
+ double floatSize = theSize;
133
+ if (theSize<1023)
134
+ return([NSString stringWithFormat:@"%lli bytes",theSize]);
135
+ floatSize = floatSize / 1024;
136
+ if (floatSize<1023)
137
+ return([NSString stringWithFormat:@"%1.1f KB",floatSize]);
138
+ floatSize = floatSize / 1024;
139
+ if (floatSize<1023)
140
+ return([NSString stringWithFormat:@"%1.1f MB",floatSize]);
141
+ floatSize = floatSize / 1024;
142
+
143
+ return([NSString stringWithFormat:@"%1.1f GB",floatSize]);
144
+ }
145
+
146
+ - (NSString*)status
147
+ {
148
+ int64_t sent = 0, toSend = 0;
149
+ for(NSURLSessionUploadTask *task in tasks) {
150
+ sent += task.countOfBytesSent;
151
+ toSend += task.countOfBytesExpectedToSend;
152
+ }
153
+ return [NSString stringWithFormat:@"%@ being uploaded (%@ of %@)\nFiles on disk: %@",
154
+ [tasks valueForKeyPath:@"taskDescription"],
155
+ stringFromFileSize(sent),
156
+ stringFromFileSize(toSend),
157
+
158
+ [[NSFileManager defaultManager]
159
+ contentsOfDirectoryAtPath:NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]
160
+ error:NULL]
161
+ ];
162
+ }
163
+
164
+
165
+ #pragma mark -
166
+ // v3.5 Phase 4: forward upload progress as syncProgress (0..100).
167
+ - (void)URLSession:(NSURLSession *)session
168
+ task:(NSURLSessionTask *)task
169
+ didSendBodyData:(int64_t)bytesSent
170
+ totalBytesSent:(int64_t)totalBytesSent
171
+ totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
172
+ {
173
+ if (totalBytesExpectedToSend <= 0) return;
174
+ NSInteger progress = (NSInteger)((totalBytesSent * 100) / totalBytesExpectedToSend);
175
+ if (progress < 0) progress = 0;
176
+ if (progress > 100) progress = 100;
177
+ [[NSNotificationCenter defaultCenter]
178
+ postNotificationName:MAURBackgroundSyncDidProgressNotification
179
+ object:self
180
+ userInfo:@{@"progress": @(progress)}];
181
+ }
182
+
183
+ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error
184
+ {
185
+ NSInteger statusCode = [(NSHTTPURLResponse *)task.response statusCode];
186
+
187
+ DDLogInfo(@"Finished uploading task %zu %@: %@ %@, HTTP %ld", (unsigned long)[task taskIdentifier], task.originalRequest.URL, error ?: @"Success", task.response, (long)statusCode);
188
+
189
+ [tasks removeObject:task];
190
+ NSURL *fullPath = [NSURL fileURLWithPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:task.taskDescription]];
191
+ [[NSFileManager defaultManager] removeItemAtURL:fullPath error:NULL];
192
+
193
+ if (statusCode == 285)
194
+ {
195
+ // Okay, but we don't need to continue sending these
196
+ DDLogDebug(@"Locations were uploaded to the server, and received an \"HTTP 285 Updates Not Required\"");
197
+
198
+ dispatch_async(dispatch_get_main_queue(), ^{
199
+ if (_delegate && [_delegate respondsToSelector:@selector(backgroundSyncRequestedAbortUpdates:)])
200
+ {
201
+ [_delegate backgroundSyncRequestedAbortUpdates:self];
202
+ }
203
+ });
204
+ }
205
+
206
+ if (statusCode == 401)
207
+ {
208
+ dispatch_async(dispatch_get_main_queue(), ^{
209
+ if (_delegate && [_delegate respondsToSelector:@selector(backgroundSyncHttpAuthorizationUpdates:)])
210
+ {
211
+ [_delegate backgroundSyncHttpAuthorizationUpdates:self];
212
+ }
213
+ });
214
+ }
215
+
216
+ // v3.5 Phase 4: emit syncSuccess / syncError.
217
+ NSNumber *sentNum = objc_getAssociatedObject(task, "locationsSent");
218
+ NSInteger locationsSent = sentNum != nil ? [sentNum integerValue] : 0;
219
+ BOOL isStatusOkay = (statusCode >= 200 && statusCode < 300);
220
+
221
+ dispatch_async(dispatch_get_main_queue(), ^{
222
+ if (error != nil) {
223
+ // v4.5.1 — restore SyncPending → PostPending so the failed locations get retried
224
+ // on the next sync window. Without this, a single network drop loses everything.
225
+ NSError *restErr = nil;
226
+ [[MAURSQLiteLocationDAO sharedInstance] restoreFailedSyncLocations:&restErr];
227
+ NSString *msg = error.localizedDescription ?: @"";
228
+ if (_delegate && [_delegate respondsToSelector:@selector(backgroundSyncFailed:httpStatus:message:)]) {
229
+ [_delegate backgroundSyncFailed:self httpStatus:0 message:msg];
230
+ }
231
+ [[NSNotificationCenter defaultCenter]
232
+ postNotificationName:MAURBackgroundSyncDidFailNotification
233
+ object:self
234
+ userInfo:@{@"httpStatus": @0, @"message": msg}];
235
+ } else if (!isStatusOkay) {
236
+ // v4.5.1 — server-side failure (5xx, 4xx other than 285/401): also restore the rows.
237
+ NSError *restErr = nil;
238
+ [[MAURSQLiteLocationDAO sharedInstance] restoreFailedSyncLocations:&restErr];
239
+ NSString *msg = [NSString stringWithFormat:@"HTTP %ld", (long)statusCode];
240
+ if (_delegate && [_delegate respondsToSelector:@selector(backgroundSyncFailed:httpStatus:message:)]) {
241
+ [_delegate backgroundSyncFailed:self httpStatus:statusCode message:msg];
242
+ }
243
+ [[NSNotificationCenter defaultCenter]
244
+ postNotificationName:MAURBackgroundSyncDidFailNotification
245
+ object:self
246
+ userInfo:@{@"httpStatus": @(statusCode), @"message": msg}];
247
+ } else {
248
+ // v4.5.1: drop SYNC_PENDING locations whose recorded_at is <= the captured upload-start
249
+ // cutoff. This preserves any new locations persisted DURING the upload (race window).
250
+ NSNumber *cutoffNum = objc_getAssociatedObject(task, "uploadCutoff");
251
+ NSTimeInterval cutoff = cutoffNum != nil ? [cutoffNum doubleValue] : [[NSDate date] timeIntervalSince1970];
252
+ NSError *delErr = nil;
253
+ BOOL deleted = [[MAURSQLiteLocationDAO sharedInstance] deleteSyncedLocationsBefore:cutoff error:&delErr];
254
+ if (!deleted) {
255
+ NSLog(@"deleteSyncedLocationsBefore after success failed: %@", delErr.localizedDescription ?: @"unknown");
256
+ }
257
+ if (_delegate && [_delegate respondsToSelector:@selector(backgroundSyncSucceeded:locationsSent:)]) {
258
+ [_delegate backgroundSyncSucceeded:self locationsSent:locationsSent];
259
+ }
260
+ [[NSNotificationCenter defaultCenter]
261
+ postNotificationName:MAURBackgroundSyncDidSucceedNotification
262
+ object:self
263
+ userInfo:@{@"sent": @(locationsSent)}];
264
+ }
265
+ });
266
+ }
267
+
268
+ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
269
+ {
270
+ DDLogInfo(@"Response:: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
271
+ }
272
+
273
+ - (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error
274
+ {
275
+ DDLogError(@"Autosync failed :( %@", error);
276
+ }
277
+
278
+ - (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
279
+ {
280
+ DDLogInfo(@"finished events for bg session");
281
+ }
282
+
283
+ @end
@@ -0,0 +1,25 @@
1
+ //
2
+ // MAURBackgroundTaskManager.h
3
+ // BackgroundGeolocation
4
+ //
5
+ // Created by Joel and Vomako (http://stackoverflow.com/a/27664620)
6
+ //
7
+
8
+ #ifndef MAURBackgroundTaskManager_h
9
+ #define MAURBackgroundTaskManager_h
10
+
11
+
12
+ #endif /* MAURBackgroundTaskManager_h */
13
+
14
+ typedef void (^CompletionBlock)(void);
15
+
16
+
17
+ @interface MAURBackgroundTaskManager : NSObject
18
+
19
+ + (id) sharedTasks;
20
+
21
+ - (NSUInteger)beginTask;
22
+ - (NSUInteger)beginTaskWithCompletionHandler:(CompletionBlock)_completion;
23
+ - (void)endTaskWithKey:(NSUInteger)_key;
24
+
25
+ @end
@@ -0,0 +1,105 @@
1
+ //
2
+ // MAURBackgroundTaskManager.m
3
+ // BackgroundGeolocation
4
+ //
5
+ // Created by Joel and Vomako (http://stackoverflow.com/a/27664620)
6
+ //
7
+
8
+ #import <UIKit/UIKit.h>
9
+ #import "MAURBackgroundTaskManager.h"
10
+
11
+ @interface MAURBackgroundTaskManager()
12
+
13
+ @property NSUInteger taskKeyCounter;
14
+ @property NSMutableDictionary *dictTaskIdentifiers;
15
+ @property NSMutableDictionary *dictTaskCompletionBlocks;
16
+
17
+ @end
18
+
19
+ @implementation MAURBackgroundTaskManager
20
+
21
+ + (id)sharedTasks {
22
+ static MAURBackgroundTaskManager *sharedTasks = nil;
23
+ static dispatch_once_t onceToken;
24
+ dispatch_once(&onceToken, ^{
25
+ sharedTasks = [[self alloc] init];
26
+ });
27
+ return sharedTasks;
28
+ }
29
+
30
+ - (id)init
31
+ {
32
+ self = [super init];
33
+ if (self) {
34
+
35
+ [self setTaskKeyCounter:0];
36
+ [self setDictTaskIdentifiers:[NSMutableDictionary dictionary]];
37
+ [self setDictTaskCompletionBlocks:[NSMutableDictionary dictionary]];
38
+ }
39
+ return self;
40
+ }
41
+
42
+ - (NSUInteger)beginTask
43
+ {
44
+ return [self beginTaskWithCompletionHandler:nil];
45
+ }
46
+
47
+ - (NSUInteger)beginTaskWithCompletionHandler:(CompletionBlock)_completion;
48
+ {
49
+ //read the counter and increment it
50
+ NSUInteger taskKey;
51
+ @synchronized(self) {
52
+
53
+ taskKey = self.taskKeyCounter;
54
+ self.taskKeyCounter++;
55
+
56
+ }
57
+
58
+ //tell the OS to start a task that should continue in the background if needed
59
+ NSUInteger taskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
60
+ [self endTaskWithKey:taskKey];
61
+ }];
62
+
63
+ //add this task identifier to the active task dictionary
64
+ [self.dictTaskIdentifiers setObject:[NSNumber numberWithUnsignedLong:taskId] forKey:[NSNumber numberWithUnsignedLong:taskKey]];
65
+
66
+ //store the completion block (if any)
67
+ if (_completion) [self.dictTaskCompletionBlocks setObject:_completion forKey:[NSNumber numberWithUnsignedLong:taskKey]];
68
+
69
+ //return the dictionary key
70
+ return taskKey;
71
+ }
72
+
73
+ - (void)endTaskWithKey:(NSUInteger)_key
74
+ {
75
+ @synchronized(self.dictTaskCompletionBlocks) {
76
+
77
+ //see if this task has a completion block
78
+ CompletionBlock completion = [self.dictTaskCompletionBlocks objectForKey:[NSNumber numberWithUnsignedLong:_key]];
79
+ if (completion) {
80
+
81
+ //run the completion block and remove it from the completion block dictionary
82
+ completion();
83
+ [self.dictTaskCompletionBlocks removeObjectForKey:[NSNumber numberWithUnsignedLong:_key]];
84
+
85
+ }
86
+
87
+ }
88
+
89
+ @synchronized(self.dictTaskIdentifiers) {
90
+
91
+ //see if this task has been ended yet
92
+ NSNumber *taskId = [self.dictTaskIdentifiers objectForKey:[NSNumber numberWithUnsignedLong:_key]];
93
+ if (taskId) {
94
+
95
+ //end the task and remove it from the active task dictionary
96
+ [[UIApplication sharedApplication] endBackgroundTask:[taskId unsignedLongValue]];
97
+ [self.dictTaskIdentifiers removeObjectForKey:[NSNumber numberWithUnsignedLong:_key]];
98
+
99
+ NSLog(@"Task ended");
100
+ }
101
+
102
+ }
103
+ }
104
+
105
+ @end
@@ -0,0 +1,99 @@
1
+ //
2
+ // MAURConfig.h
3
+ // BackgroundGeolocation
4
+ //
5
+ // Created by Marian Hello on 11/06/16.
6
+ //
7
+
8
+ #ifndef MAURConfig_h
9
+ #define MAURConfig_h
10
+
11
+ #import <Foundation/Foundation.h>
12
+ #import <CoreLocation/CoreLocation.h>
13
+
14
+ enum {
15
+ DISTANCE_FILTER_PROVIDER = 0,
16
+ ACTIVITY_PROVIDER = 1,
17
+ RAW_PROVIDER = 2
18
+ };
19
+
20
+ @interface MAURConfig : NSObject <NSCopying>
21
+
22
+ @property NSNumber *stationaryRadius;
23
+ @property NSNumber *distanceFilter;
24
+ @property NSNumber *desiredAccuracy;
25
+ @property NSNumber *_debug;
26
+ @property NSString *activityType;
27
+ @property NSNumber *activitiesInterval;
28
+ @property NSNumber *_stopOnTerminate;
29
+ @property NSString *url;
30
+ @property NSString *syncUrl;
31
+ @property NSNumber *syncThreshold;
32
+ @property NSNumber *syncEnabled;
33
+ @property NSMutableDictionary* httpHeaders;
34
+ // v3.3 Phase 2: backend-agnostic HTTP transport
35
+ @property NSString *httpMethod; // POST | GET | PUT | PATCH (default POST)
36
+ @property NSString *syncHttpMethod; // POST | GET | PUT | PATCH (default POST)
37
+ @property NSString *httpMode; // batch | single (default batch)
38
+ @property NSString *syncMode; // batch | single (default batch)
39
+ @property NSMutableDictionary* queryParams; // static placeholder values for URL templating
40
+ // v3.4 Phase 3: location API modernization
41
+ @property NSNumber *_showsBackgroundLocationIndicator; // iOS 11+: show blue bar when app uses location in background
42
+ // v3.5 Phase 4: diagnostics
43
+ @property NSNumber *heartbeatInterval; // ms; 0 disables (default)
44
+ @property NSString *mockLocationPolicy; // allow | flag | drop (default allow)
45
+ // v4.0 Phase 6: driver insights — passed through as a dictionary; the facade reads keys at runtime.
46
+ @property NSDictionary *drivingEvents;
47
+ // v4.4: stamp battery percentage + charging state onto every location (default ON).
48
+ @property NSNumber *includeBattery;
49
+ // v4.5.2: provider hardening
50
+ /** 0-100. Activity-recognition transitions below this confidence are ignored. Default 50. */
51
+ @property NSNumber *activityConfidenceThreshold;
52
+ /** Discard fixes whose accuracy (m) is worse than this. nil = no filter. */
53
+ @property NSNumber *maxAcceptedAccuracy;
54
+ @property NSNumber *_saveBatteryOnBackground;
55
+ @property NSNumber *maxLocations;
56
+ @property NSNumber *_pauseLocationUpdates;
57
+ @property NSNumber *locationProvider;
58
+ @property NSObject *_template;
59
+
60
+ - (instancetype) initWithDefaults;
61
+ + (instancetype) fromDictionary:(NSDictionary*)config;
62
+ + (instancetype) merge:(MAURConfig*)config withConfig:(MAURConfig*)newConfig;
63
+ + (NSDictionary*) getDefaultTemplate;
64
+
65
+ - (BOOL) hasStationaryRadius;
66
+ - (BOOL) hasDistanceFilter;
67
+ - (BOOL) hasDesiredAccuracy;
68
+ - (BOOL) hasDebug;
69
+ - (BOOL) hasActivityType;
70
+ - (BOOL) hasStopOnTerminate;
71
+ - (BOOL) hasUrl;
72
+ - (BOOL) hasValidUrl;
73
+ - (BOOL) hasSyncUrl;
74
+ - (BOOL) hasValidSyncUrl;
75
+ - (BOOL) hasSyncThreshold;
76
+ - (BOOL) hasSyncEnabled;
77
+ - (BOOL) syncEnabled;
78
+ - (BOOL) hasHttpHeaders;
79
+ - (BOOL) hasSaveBatteryOnBackground;
80
+ - (BOOL) hasShowsBackgroundLocationIndicator;
81
+ - (BOOL) showsBackgroundLocationIndicator;
82
+ - (BOOL) hasMaxLocations;
83
+ - (BOOL) hasPauseLocationUpdates;
84
+ - (BOOL) hasLocationProvider;
85
+ - (BOOL) hasTemplate;
86
+ - (BOOL) hasActivitiesInterval;
87
+ - (BOOL) isDebugging;
88
+ - (BOOL) stopOnTerminate;
89
+ - (BOOL) saveBatteryOnBackground;
90
+ - (BOOL) pauseLocationUpdates;
91
+ - (CLActivityType) decodeActivityType;
92
+ - (NSInteger) decodeDesiredAccuracy;
93
+ - (NSString*) getHttpHeadersAsString:(NSError * __autoreleasing *)outError;
94
+ - (NSString*) getTemplateAsString:(NSError * __autoreleasing *)outError;
95
+ - (NSDictionary*) toDictionary;
96
+
97
+ @end;
98
+
99
+ #endif /* MAURConfig_h */