Skip to content

Commit

Permalink
Add configuration profile options (#43)
Browse files Browse the repository at this point in the history
* Port Radius Profile Configuration (#36)

* Switch to @available for version checking

This requires Xcode 9.x.

* Port Radius Profile Configuration

- Creates new class MMEEventsService to manage the creation and distribution of MMEEventsConfiguration objects/configurations.
- Expands MMEEventsConfiguration to include a variable hibernation radius configuration and potentially additional configurations in the future. A user may access the variable radius by setting both "MMEEventsProfile" (with the appropriate key "VariableGeofence") and "MMEGeofenceRadius" with a desired radius (within a range we've set) in the applications plist. If "MMEEventsProfile" is set in plist without choosing a radius then a median radius will be the default. 
- Modifies MMELocationManager and MMEEventsManager to use MMEEventsService configuration
- Adds and repairs cedar tests

* Fix bug with geofence creation related to custom profile

geofence were being created too often when the profile was set to a wide geofence radius.

* Update symbols

* Fix nullable singleton

* Follow bracket convention

* Fix race condition in cedar test

"created" NSDate was causing a failure some of the time when the date time was off by a second.

* Remove hard-coded date string
  • Loading branch information
rclee authored Jun 1, 2018
1 parent 16ad59a commit 0be580c
Show file tree
Hide file tree
Showing 11 changed files with 175 additions and 22 deletions.
10 changes: 10 additions & 0 deletions MapboxMobileEvents.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@
40FB437D1EFAFAE900EC5BC0 /* MMETimerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 40FB437B1EFAFAE900EC5BC0 /* MMETimerManager.m */; };
40FB437E1EFAFAE900EC5BC0 /* MMETimerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 40FB437B1EFAFAE900EC5BC0 /* MMETimerManager.m */; };
40FB43801EFAFDCF00EC5BC0 /* MMETimerManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 40FB437F1EFAFDCF00EC5BC0 /* MMETimerManagerTests.m */; };
AC518E072034C0B500EBC820 /* MMEEventsService.h in Headers */ = {isa = PBXBuildFile; fileRef = AC518E052034C0B500EBC820 /* MMEEventsService.h */; };
AC518E082034C0B500EBC820 /* MMEEventsService.m in Sources */ = {isa = PBXBuildFile; fileRef = AC518E062034C0B500EBC820 /* MMEEventsService.m */; };
AC518E092034C3E700EBC820 /* MMEEventsService.m in Sources */ = {isa = PBXBuildFile; fileRef = AC518E062034C0B500EBC820 /* MMEEventsService.m */; };
AC611F271FCDED2F00ABBF6D /* MMEEventLogReportViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = AC611F251FCDED2F00ABBF6D /* MMEEventLogReportViewController.h */; };
AC611F281FCDED2F00ABBF6D /* MMEEventLogReportViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AC611F261FCDED2F00ABBF6D /* MMEEventLogReportViewController.m */; };
ACB6F21E1F7BF71B0032A916 /* MMELocationManagerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACB6F21D1F7BF71B0032A916 /* MMELocationManagerTests.mm */; };
Expand Down Expand Up @@ -283,6 +286,8 @@
40FB437A1EFAFAE900EC5BC0 /* MMETimerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMETimerManager.h; sourceTree = "<group>"; };
40FB437B1EFAFAE900EC5BC0 /* MMETimerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMETimerManager.m; sourceTree = "<group>"; };
40FB437F1EFAFDCF00EC5BC0 /* MMETimerManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMETimerManagerTests.m; sourceTree = "<group>"; };
AC518E052034C0B500EBC820 /* MMEEventsService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MMEEventsService.h; sourceTree = "<group>"; };
AC518E062034C0B500EBC820 /* MMEEventsService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MMEEventsService.m; sourceTree = "<group>"; };
AC611F251FCDED2F00ABBF6D /* MMEEventLogReportViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MMEEventLogReportViewController.h; sourceTree = "<group>"; };
AC611F261FCDED2F00ABBF6D /* MMEEventLogReportViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MMEEventLogReportViewController.m; sourceTree = "<group>"; };
ACB6F21D1F7BF71B0032A916 /* MMELocationManagerTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MMELocationManagerTests.mm; sourceTree = "<group>"; };
Expand Down Expand Up @@ -384,6 +389,8 @@
4036EFBD1ED37D56009C40BA /* MMEEventLogger.m */,
AC611F251FCDED2F00ABBF6D /* MMEEventLogReportViewController.h */,
AC611F261FCDED2F00ABBF6D /* MMEEventLogReportViewController.m */,
AC518E052034C0B500EBC820 /* MMEEventsService.h */,
AC518E062034C0B500EBC820 /* MMEEventsService.m */,
40FB43751EF9EA7800EC5BC0 /* MMEEventsConfiguration.h */,
40FB43761EF9EA7800EC5BC0 /* MMEEventsConfiguration.m */,
40C9E2791EA542BC00744FE7 /* MMEEventsManager.h */,
Expand Down Expand Up @@ -600,6 +607,7 @@
40834B9F1FDF62C900C1BD0D /* MMENamespacedDependencies.h in Headers */,
409115301F16AE6100F4250B /* MMETrustKitWrapper.h in Headers */,
40C611861F18319000E30A6C /* TSKPinningValidator_Private.h in Headers */,
AC518E072034C0B500EBC820 /* MMEEventsService.h in Headers */,
40C611831F18319000E30A6C /* TSKPinningValidator.h in Headers */,
40C9E27B1EA542BC00744FE7 /* MMEEventsManager.h in Headers */,
40C611731F18319000E30A6C /* TSKReportsRateLimiter.h in Headers */,
Expand Down Expand Up @@ -804,6 +812,7 @@
40C611681F18319000E30A6C /* TSKSPKIHashCache.m in Sources */,
40F16C971F04514100DF338D /* MMEReachability.m in Sources */,
40C9E2801EA5473F00744FE7 /* MMELocationManager.m in Sources */,
AC518E082034C0B500EBC820 /* MMEEventsService.m in Sources */,
40C611841F18319000E30A6C /* TSKPinningValidator.m in Sources */,
AC611F281FCDED2F00ABBF6D /* MMEEventLogReportViewController.m in Sources */,
40C611641F18319000E30A6C /* ssl_pin_verifier.m in Sources */,
Expand Down Expand Up @@ -874,6 +883,7 @@
408596671ED086F4003BD29D /* MMECommonEventData.m in Sources */,
408596631ED086E8003BD29D /* CLLocation+MMEMobileEvents.m in Sources */,
40C611781F18319000E30A6C /* vendor_identifier.m in Sources */,
AC518E092034C3E700EBC820 /* MMEEventsService.m in Sources */,
408596611ED086E2003BD29D /* MMEAPIClient.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
3 changes: 3 additions & 0 deletions MapboxMobileEvents/MMEEventsConfiguration.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>

@interface MMEEventsConfiguration : NSObject

@property (nonatomic) NSUInteger eventFlushCountThreshold;
@property (nonatomic) NSUInteger eventFlushSecondsThreshold;
@property (nonatomic) NSTimeInterval instanceIdentifierRotationTimeInterval;
@property (nonatomic) CLLocationDistance locationManagerHibernationRadius;

+ (instancetype)defaultEventsConfiguration;
+ (instancetype)eventsConfigurationWithVariableRadius:(CLLocationDistance)radius;

@end
27 changes: 24 additions & 3 deletions MapboxMobileEvents/MMEEventsConfiguration.m
Original file line number Diff line number Diff line change
@@ -1,12 +1,33 @@
#import "MMEEventsConfiguration.h"

static const CLLocationDistance kHibernationRadiusDefault = 300.0;
static const CLLocationDistance kHibernationRadiusWide = 1200.0;
static const NSUInteger kEventFlushCountThresholdDefault = 180;
static const NSUInteger kEventFlushSecondsThresholdDefault = 180;
static const NSTimeInterval kInstanceIdentifierRotationTimeIntervalDefault = 24 * 3600; // 24 hours

@implementation MMEEventsConfiguration

+ (instancetype)defaultEventsConfiguration {
MMEEventsConfiguration *configuration = [[MMEEventsConfiguration alloc] init];
configuration.eventFlushCountThreshold = 180;
configuration.eventFlushSecondsThreshold = 180;
configuration.instanceIdentifierRotationTimeInterval = 24 * 3600; // 24 hours
configuration.eventFlushCountThreshold = kEventFlushCountThresholdDefault;
configuration.eventFlushSecondsThreshold = kEventFlushSecondsThresholdDefault;
configuration.instanceIdentifierRotationTimeInterval = kInstanceIdentifierRotationTimeIntervalDefault;
configuration.locationManagerHibernationRadius = kHibernationRadiusDefault;
return configuration;
}

+ (instancetype)eventsConfigurationWithVariableRadius:(CLLocationDistance)radius {
MMEEventsConfiguration *configuration = [[MMEEventsConfiguration alloc] init];
configuration.eventFlushCountThreshold = kEventFlushCountThresholdDefault;
configuration.eventFlushSecondsThreshold = kEventFlushSecondsThresholdDefault;
configuration.instanceIdentifierRotationTimeInterval = kInstanceIdentifierRotationTimeIntervalDefault;

if (radius == 0) radius = kHibernationRadiusWide / 2; //return a median radius if no variable radius is set
else if (radius < kHibernationRadiusDefault) radius = kHibernationRadiusDefault;
else if (radius > kHibernationRadiusWide) radius = kHibernationRadiusWide;

configuration.locationManagerHibernationRadius = radius;
return configuration;
}

Expand Down
7 changes: 4 additions & 3 deletions MapboxMobileEvents/MMEEventsManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#import "MMENSDateWrapper.h"
#import "MMECategoryLoader.h"
#import "CLLocation+MMEMobileEvents.h"
#import "MMEEventsService.h"
#import <CoreLocation/CoreLocation.h>

@interface MMEEventsManager () <MMELocationManagerDelegate>
Expand All @@ -37,12 +38,12 @@ @implementation MMEEventsManager
+ (instancetype)sharedManager {
static MMEEventsManager *_sharedManager;
static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{
[MMECategoryLoader loadCategories];
_sharedManager = [[MMEEventsManager alloc] init];
});

return _sharedManager;
}

Expand All @@ -54,7 +55,7 @@ - (instancetype)init {
_accountType = 0;
_eventQueue = [NSMutableArray array];
_commonEventData = [[MMECommonEventData alloc] init];
_configuration = [MMEEventsConfiguration defaultEventsConfiguration];
_configuration = [[MMEEventsService sharedService] configuration];
_uniqueIdentifer = [[MMEUniqueIdentifier alloc] initWithTimeInterval:_configuration.instanceIdentifierRotationTimeInterval];
_application = [[MMEUIApplicationWrapper alloc] init];
_dateWrapper = [[MMENSDateWrapper alloc] init];
Expand Down
15 changes: 15 additions & 0 deletions MapboxMobileEvents/MMEEventsService.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import "MMEEventsConfiguration.h"

NS_ASSUME_NONNULL_BEGIN

@interface MMEEventsService : NSObject

@property (nonatomic) MMEEventsConfiguration *configuration;

+ (instancetype)sharedService;

@end

NS_ASSUME_NONNULL_END
36 changes: 36 additions & 0 deletions MapboxMobileEvents/MMEEventsService.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#import "MMEEventsService.h"

NSString *const kMMEEventsProfile = @"MMEEventsProfile";
NSString *const kMMERadiusSize = @"MMEGeofenceRadius";

static NSString *const kConfigHibernationRadiusVariableKey = @"VariableGeofence";

@implementation MMEEventsService

- (instancetype) init {
self = [super init];
if (self) {
self.configuration = [self configurationFromKey:[[NSBundle mainBundle] objectForInfoDictionaryKey:kMMEEventsProfile]];
}
return self;
}

+ (instancetype)sharedService {
static dispatch_once_t onceToken;
static MMEEventsService *_sharedService;
dispatch_once(&onceToken, ^{
_sharedService = [[self alloc] init];
});
return _sharedService;
}

- (MMEEventsConfiguration *)configurationFromKey:(NSString *)key {
if ([key isEqualToString:kConfigHibernationRadiusVariableKey]) {
return [MMEEventsConfiguration eventsConfigurationWithVariableRadius:[[[NSBundle mainBundle] objectForInfoDictionaryKey:kMMERadiusSize] doubleValue]];
} else {
return [MMEEventsConfiguration defaultEventsConfiguration];
}
return nil;
}

@end
25 changes: 15 additions & 10 deletions MapboxMobileEvents/MMELocationManager.m
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#import "MMELocationManager.h"
#import "MMEUIApplicationWrapper.h"
#import "MMEDependencyManager.h"
#import "MMEEventsService.h"
#import "MMEEventsConfiguration.h"
#import <CoreLocation/CoreLocation.h>

static const NSTimeInterval MMELocationManagerHibernationTimeout = 300.0;
static const NSTimeInterval MMELocationManagerHibernationPollInterval = 5.0;

const CLLocationDistance MMELocationManagerHibernationRadius = 300.0;
const CLLocationDistance MMELocationManagerDistanceFilter = 5.0;
const CLLocationDistance MMERadiusAccuracyMax = 300.0;

NSString * const MMELocationManagerRegionIdentifier = @"MMELocationManagerRegionIdentifier.fence.center";

Expand All @@ -19,6 +21,7 @@ @interface MMELocationManager () <CLLocationManagerDelegate>
@property (nonatomic) NSDate *backgroundLocationServiceTimeoutAllowedDate;
@property (nonatomic) NSTimer *backgroundLocationServiceTimeoutTimer;
@property (nonatomic) BOOL hostAppHasBackgroundCapability;
@property (nonatomic) MMEEventsConfiguration *configuration;

@end

Expand All @@ -30,6 +33,7 @@ - (instancetype)init {
_application = [[MMEUIApplicationWrapper alloc] init];
NSArray *backgroundModes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"];
_hostAppHasBackgroundCapability = [backgroundModes containsObject:@"location"];
_configuration = [[MMEEventsService sharedService] configuration];
}
return self;
}
Expand Down Expand Up @@ -89,11 +93,11 @@ - (void)configurePassiveLocationManager {

- (void)startLocationServices {
CLAuthorizationStatus authorizationStatus = [CLLocationManager authorizationStatus];

BOOL authorizedAlways = authorizationStatus == kCLAuthorizationStatusAuthorizedAlways;

if (authorizedAlways || authorizationStatus == kCLAuthorizationStatusAuthorizedWhenInUse) {

// If the host app can run in the background with `always` location permissions then allow background
// updates and start the significant location change service and background timeout timer
if (authorizedAlways && self.hostAppHasBackgroundCapability) {
Expand All @@ -103,7 +107,7 @@ - (void)startLocationServices {
self.locationManager.allowsBackgroundLocationUpdates = YES;
}
}

// If authorization status is when in use specifically, allow background location updates based on
// if the library is configured to do so. Don't worry about significant location change and the
// background timer (just above) since all use cases for background collection with in use only
Expand All @@ -121,7 +125,7 @@ - (void)startLocationServices {

[self.locationManager startUpdatingLocation];
self.updatingLocation = YES;

if ([self.delegate respondsToSelector:@selector(locationManagerDidStartLocationUpdates:)]) {
[self.delegate locationManagerDidStartLocationUpdates:self];
}
Expand All @@ -132,13 +136,13 @@ - (void)timeoutAllowedCheck {
if (!self.isUpdatingLocation) {
return;
}

if (self.application.applicationState == UIApplicationStateActive ||
self.application.applicationState == UIApplicationStateInactive ) {
[self startBackgroundTimeoutTimer];
return;
}

NSTimeInterval timeIntervalSinceTimeoutAllowed = [[NSDate date] timeIntervalSinceDate:self.backgroundLocationServiceTimeoutAllowedDate];
if (timeIntervalSinceTimeoutAllowed > 0) {
[self.locationManager stopUpdatingLocation];
Expand All @@ -156,7 +160,7 @@ - (void)startBackgroundTimeoutTimer {
}

- (void)establishRegionMonitoringForLocation:(CLLocation *)location {
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:location.coordinate radius:MMELocationManagerHibernationRadius identifier:MMELocationManagerRegionIdentifier];
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:location.coordinate radius:self.configuration.locationManagerHibernationRadius identifier:MMELocationManagerRegionIdentifier];
region.notifyOnEntry = NO;
region.notifyOnExit = YES;
[self.locationManager startMonitoringForRegion:region];
Expand All @@ -178,7 +182,7 @@ - (void)locationManager:(CLLocationManager *)locationManager didUpdateLocations:
if (location.speed > 0.0) {
[self startBackgroundTimeoutTimer];
}
if ([self.locationManager.monitoredRegions anyObject] == nil || location.horizontalAccuracy < MMELocationManagerHibernationRadius) {
if ([self.locationManager.monitoredRegions anyObject] == nil || location.horizontalAccuracy < MMERadiusAccuracyMax) {
[self establishRegionMonitoringForLocation:location];
}
if ([self.delegate respondsToSelector:@selector(locationManager:didUpdateLocations:)]) {
Expand All @@ -204,3 +208,4 @@ - (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)locationMana
}

@end

28 changes: 24 additions & 4 deletions MapboxMobileEvents/MMENamespacedDependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
#define MMEEventsManager __NS_SYMBOL(MMEEventsManager)
#endif

#ifndef MMEEventsService
#define MMEEventsService __NS_SYMBOL(MMEEventsService)
#endif

#ifndef MMELocationManager
#define MMELocationManager __NS_SYMBOL(MMELocationManager)
#endif
Expand Down Expand Up @@ -155,6 +159,14 @@
#define convertPinsToHpkpPins __NS_SYMBOL(convertPinsToHpkpPins)
#endif

#ifndef __clang_at_available_requires_core_foundation_framework
#define __clang_at_available_requires_core_foundation_framework __NS_SYMBOL(__clang_at_available_requires_core_foundation_framework)
#endif

#ifndef __clang_at_available_requires_core_foundation_framework
#define __clang_at_available_requires_core_foundation_framework __NS_SYMBOL(__clang_at_available_requires_core_foundation_framework)
#endif

// Externs
#ifndef _loggerBlock
#define _loggerBlock __NS_SYMBOL(_loggerBlock)
Expand Down Expand Up @@ -260,6 +272,14 @@
#define kTSKAlgorithmEcDsaSecp384r1 __NS_SYMBOL(kTSKAlgorithmEcDsaSecp384r1)
#endif

#ifndef kMMEEventsProfile
#define kMMEEventsProfile __NS_SYMBOL(kMMEEventsProfile)
#endif

#ifndef kMMERadiusSize
#define kMMERadiusSize __NS_SYMBOL(kMMERadiusSize)
#endif

#ifndef MMEApplicationStateForeground
#define MMEApplicationStateForeground __NS_SYMBOL(MMEApplicationStateForeground)
#endif
Expand Down Expand Up @@ -560,14 +580,14 @@
#define kMMEReachabilityChangedNotification __NS_SYMBOL(kMMEReachabilityChangedNotification)
#endif

#ifndef MMELocationManagerHibernationRadius
#define MMELocationManagerHibernationRadius __NS_SYMBOL(MMELocationManagerHibernationRadius)
#endif

#ifndef MMELocationManagerDistanceFilter
#define MMELocationManagerDistanceFilter __NS_SYMBOL(MMELocationManagerDistanceFilter)
#endif

#ifndef MMERadiusAccuracyMax
#define MMERadiusAccuracyMax __NS_SYMBOL(MMERadiusAccuracyMax)
#endif

#ifndef MMELocationManagerRegionIdentifier
#define MMELocationManagerRegionIdentifier __NS_SYMBOL(MMELocationManagerRegionIdentifier)
#endif
Expand Down
Loading

0 comments on commit 0be580c

Please sign in to comment.