diff --git a/include/mbgl/ios/MGLMapboxEvents.h b/include/mbgl/ios/MGLMapboxEvents.h index e51371368db..2af3d8b168c 100644 --- a/include/mbgl/ios/MGLMapboxEvents.h +++ b/include/mbgl/ios/MGLMapboxEvents.h @@ -29,6 +29,8 @@ extern NSString *const MGLEventGestureRotateStart; + (void) setToken:(NSString *)token; + (void) setAppName:(NSString *)appName; + (void) setAppVersion:(NSString *)appVersion; ++ (void) pauseMetricsCollection; ++ (void) resumeMetricsCollection; // You can call this method from any thread. Significant work will // be dispatched to a low-priority background queue and all diff --git a/include/mbgl/ios/MGLMetricsLocationManager.h b/include/mbgl/ios/MGLMetricsLocationManager.h index 7281d050106..5f3b5681872 100644 --- a/include/mbgl/ios/MGLMetricsLocationManager.h +++ b/include/mbgl/ios/MGLMetricsLocationManager.h @@ -2,8 +2,10 @@ @interface MGLMetricsLocationManager : NSObject -// This method can be called from any thread. +// These methods can be called from any thread. // + (instancetype)sharedManager; ++ (void) startUpdatingLocation; ++ (void) stopUpdatingLocation; @end diff --git a/ios/app/MBXAppDelegate.m b/ios/app/MBXAppDelegate.m index f0541b99712..f2ef69ec634 100644 --- a/ios/app/MBXAppDelegate.m +++ b/ios/app/MBXAppDelegate.m @@ -1,5 +1,6 @@ #import "MBXAppDelegate.h" #import "MBXViewController.h" +#import @implementation MBXAppDelegate @@ -12,4 +13,26 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( return YES; } +/** +- (void)applicationWillEnterForeground:(UIApplication *)application +{ + // Example of how to resume Metrics Collection + + // Reasons for needing to resume: + // 1. In UIBackground and app starts listening for Location Updates where it previously had not been listening. + // 2. App is entering foreground where it had called pauseMetricsCollection. + [MGLMapboxEvents resumeMetricsCollection]; +} + +- (void)applicationDidEnterBackground:(UIApplication *)application +{ + // Example of how to pause Metrics Collection + + // Reason for needing to pause: + // 1. Either entering or already in UIBackground and app stops listening for Location Updates + // via any CLLocationManager instance it may have. + [MGLMapboxEvents pauseMetricsCollection]; +} +*/ + @end diff --git a/platform/ios/MGLMapboxEvents.m b/platform/ios/MGLMapboxEvents.m index 2dfecbd7782..346bd70aca5 100644 --- a/platform/ios/MGLMapboxEvents.m +++ b/platform/ios/MGLMapboxEvents.m @@ -71,6 +71,11 @@ @interface MGLMapboxEvents() @property (atomic) NSDateFormatter *rfc3339DateFormatter; @property (atomic) CGFloat scale; + +// The isPaused state tracker is only ever accessed from the main thread. +// +@property (nonatomic) BOOL isPaused; + // The timer is only ever accessed from the main thread. // @property (nonatomic) NSTimer *timer; @@ -168,6 +173,8 @@ - (instancetype) init { // Clear Any System TimeZone Cache [NSTimeZone resetSystemTimeZone]; [_rfc3339DateFormatter setTimeZone:[NSTimeZone systemTimeZone]]; + + _isPaused = NO; } return self; } @@ -219,6 +226,28 @@ + (void) setAppVersion:(NSString *)appVersion { [MGLMapboxEvents sharedManager].appVersion = appVersion; } +// Must be called from the main thread. +// ++ (void) pauseMetricsCollection { + assert([[NSThread currentThread] isMainThread]); + if ([MGLMapboxEvents sharedManager].isPaused) { + return; + } + [MGLMapboxEvents sharedManager].isPaused = YES; + [MGLMetricsLocationManager stopUpdatingLocation]; +} + +// Must be called from the main thread. +// ++ (void) resumeMetricsCollection { + assert([[NSThread currentThread] isMainThread]); + if (![MGLMapboxEvents sharedManager].isPaused) { + return; + } + [MGLMapboxEvents sharedManager].isPaused = NO; + [MGLMetricsLocationManager startUpdatingLocation]; +} + // Can be called from any thread. Can be called rapidly from // the UI thread, so performance is paramount. // @@ -247,6 +276,11 @@ - (void) pushEvent:(NSString *)event withAttributes:(NSDictionary *)attributeDic return; } + // Metrics Collection Has Been Paused + if (_isPaused) { + return; + } + if (!event) return; NSMutableDictionary *evt = [[NSMutableDictionary alloc] initWithDictionary:attributeDictionary];