summaryrefslogtreecommitdiff
path: root/platform/ios/src/MGLMapboxEvents.m
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ios/src/MGLMapboxEvents.m')
-rw-r--r--platform/ios/src/MGLMapboxEvents.m103
1 files changed, 67 insertions, 36 deletions
diff --git a/platform/ios/src/MGLMapboxEvents.m b/platform/ios/src/MGLMapboxEvents.m
index 4f1413d300..d59972f5bf 100644
--- a/platform/ios/src/MGLMapboxEvents.m
+++ b/platform/ios/src/MGLMapboxEvents.m
@@ -54,6 +54,9 @@ static NSString *const MGLEventKeySessionId = @"sessionId";
static NSString *const MGLEventKeyApplicationState = @"applicationState";
static NSString *const MGLEventKeyAltitude = @"altitude";
+static NSString *const MGLMapboxAccountType = @"MGLMapboxAccountType";
+static NSString *const MGLMapboxMetricsEnabled = @"MGLMapboxMetricsEnabled";
+
// SDK event source
static NSString *const MGLEventSource = @"mapbox";
@@ -124,6 +127,8 @@ const NSTimeInterval MGLFlushInterval = 180;
@property (nonatomic) NSTimer *timer;
@property (nonatomic) NSDate *instanceIDRotationDate;
@property (nonatomic) NSDate *nextTurnstileSendDate;
+@property (nonatomic) NSNumber *currentAccountTypeValue;
+@property (nonatomic) BOOL currentMetricsEnabledValue;
@end
@@ -135,10 +140,10 @@ const NSTimeInterval MGLFlushInterval = 180;
+ (void)initialize {
if (self == [MGLMapboxEvents class]) {
NSBundle *bundle = [NSBundle mainBundle];
- NSNumber *accountTypeNumber = [bundle objectForInfoDictionaryKey:@"MGLMapboxAccountType"];
+ NSNumber *accountTypeNumber = [bundle objectForInfoDictionaryKey:MGLMapboxAccountType];
[[NSUserDefaults standardUserDefaults] registerDefaults:@{
- @"MGLMapboxAccountType": accountTypeNumber ?: @0,
- @"MGLMapboxMetricsEnabled": @YES,
+ MGLMapboxAccountType: accountTypeNumber ?: @0,
+ MGLMapboxMetricsEnabled: @YES,
@"MGLMapboxMetricsDebugLoggingEnabled": @NO,
}];
}
@@ -152,8 +157,8 @@ const NSTimeInterval MGLFlushInterval = 180;
if ([NSProcessInfo instancesRespondToSelector:@selector(isLowPowerModeEnabled)]) {
isLowPowerModeEnabled = [[NSProcessInfo processInfo] isLowPowerModeEnabled];
}
- return ([[NSUserDefaults standardUserDefaults] boolForKey:@"MGLMapboxMetricsEnabled"] &&
- [[NSUserDefaults standardUserDefaults] integerForKey:@"MGLMapboxAccountType"] == 0 &&
+ return ([[NSUserDefaults standardUserDefaults] boolForKey:MGLMapboxMetricsEnabled] &&
+ [[NSUserDefaults standardUserDefaults] integerForKey:MGLMapboxAccountType] == 0 &&
!isLowPowerModeEnabled);
#endif
}
@@ -167,6 +172,9 @@ const NSTimeInterval MGLFlushInterval = 180;
- (instancetype) init {
self = [super init];
if (self) {
+ _currentAccountTypeValue = @0;
+ _currentMetricsEnabledValue = YES;
+
_appBundleId = [[NSBundle mainBundle] bundleIdentifier];
_apiClient = [[MGLAPIClient alloc] init];
@@ -249,38 +257,61 @@ const NSTimeInterval MGLFlushInterval = 180;
}
- (void)userDefaultsDidChange:(NSNotification *)notification {
- dispatch_async(dispatch_get_main_queue(), ^{
- [self pauseOrResumeMetricsCollectionIfRequired];
- });
+
+ // Guard against over calling pause / resume if the values this implementation actually
+ // cares about have not changed
+
+ if ([[notification object] respondsToSelector:@selector(objectForKey:)]) {
+ NSUserDefaults *userDefaults = [notification object];
+
+ NSNumber *accountType = [userDefaults objectForKey:MGLMapboxAccountType];
+ BOOL metricsEnabled = [[userDefaults objectForKey:MGLMapboxMetricsEnabled] boolValue];
+
+ if (![accountType isEqualToNumber:self.currentAccountTypeValue] || metricsEnabled != self.currentMetricsEnabledValue) {
+ [self pauseOrResumeMetricsCollectionIfRequired];
+ self.currentAccountTypeValue = accountType;
+ self.currentMetricsEnabledValue = metricsEnabled;
+ }
+ }
+
}
- (void)pauseOrResumeMetricsCollectionIfRequired {
- UIApplication *application = [UIApplication sharedApplication];
-
- // Prevent blue status bar when host app has `when in use` permission only and it is not in foreground
- if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse &&
- application.applicationState == UIApplicationStateBackground) {
-
- if (_backgroundTaskIdentifier == UIBackgroundTaskInvalid) {
- _backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{
- [application endBackgroundTask:_backgroundTaskIdentifier];
- _backgroundTaskIdentifier = UIBackgroundTaskInvalid;
- }];
- [self flush];
- }
-
- [self pauseMetricsCollection];
- return;
- }
-
- // Toggle pause based on current pause state, user opt-out state, and low-power state.
- BOOL enabled = [[self class] isEnabled];
- if (self.paused && enabled) {
- [self resumeMetricsCollection];
- } else if (!self.paused && !enabled) {
- [self flush];
- [self pauseMetricsCollection];
- }
+
+ // [CLLocationManager authorizationStatus] has been found to block in some cases so
+ // dispatch the call to a non-UI thread
+ dispatch_async(self.serialQueue, ^{
+ CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
+
+ // Checking application state must be done on the main thread for safety and
+ // to avoid a thread sanitizer error
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIApplication *application = [UIApplication sharedApplication];
+ UIApplicationState state = application.applicationState;
+
+ // Prevent blue status bar when host app has `when in use` permission only and it is not in foreground
+ if (status == kCLAuthorizationStatusAuthorizedWhenInUse && state == UIApplicationStateBackground) {
+ if (_backgroundTaskIdentifier == UIBackgroundTaskInvalid) {
+ _backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{
+ [application endBackgroundTask:_backgroundTaskIdentifier];
+ _backgroundTaskIdentifier = UIBackgroundTaskInvalid;
+ }];
+ [self flush];
+ }
+ [self pauseMetricsCollection];
+ return;
+ }
+
+ // Toggle pause based on current pause state, user opt-out state, and low-power state.
+ BOOL enabled = [[self class] isEnabled];
+ if (self.paused && enabled) {
+ [self resumeMetricsCollection];
+ } else if (!self.paused && !enabled) {
+ [self flush];
+ [self pauseMetricsCollection];
+ }
+ });
+ });
}
- (void)pauseMetricsCollection {
@@ -602,7 +633,7 @@ const NSTimeInterval MGLFlushInterval = 180;
BOOL metricsEnabledSettingShownInAppFlag = [shownInAppNumber boolValue];
if (!metricsEnabledSettingShownInAppFlag &&
- [[NSUserDefaults standardUserDefaults] integerForKey:@"MGLMapboxAccountType"] == 0) {
+ [[NSUserDefaults standardUserDefaults] integerForKey:MGLMapboxAccountType] == 0) {
// Opt-out is not configured in UI, so check for Settings.bundle
id defaultEnabledValue;
NSString *appSettingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
@@ -612,7 +643,7 @@ const NSTimeInterval MGLFlushInterval = 180;
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[appSettingsBundle stringByAppendingPathComponent:@"Root.plist"]];
NSArray *preferences = settings[@"PreferenceSpecifiers"];
for (NSDictionary *prefSpecification in preferences) {
- if ([prefSpecification[@"Key"] isEqualToString:@"MGLMapboxMetricsEnabled"]) {
+ if ([prefSpecification[@"Key"] isEqualToString:MGLMapboxMetricsEnabled]) {
defaultEnabledValue = prefSpecification[@"DefaultValue"];
}
}