diff options
author | Jason Wray <jason@mapbox.com> | 2016-01-06 02:28:34 -0500 |
---|---|---|
committer | Jason Wray <jason@mapbox.com> | 2016-01-09 01:21:45 -0500 |
commit | 45a0f48ea023a73d8652c6c2af94f7048a02157c (patch) | |
tree | eea95fabc4594619dd52673d23102ae684d65464 /platform | |
parent | d7fdcc73bfcab39f63e547ce2af8435a9859cb08 (diff) | |
download | qtlocation-mapboxgl-45a0f48ea023a73d8652c6c2af94f7048a02157c.tar.gz |
[ios] Add telemetry setting directly to attribution button action sheet
- Deprecate and no-op `+[MGLAccountManager mapboxMetricsEnabledSettingShownInApp]`
- Check for attribution button hiding and make sure ToS are understood
Diffstat (limited to 'platform')
-rw-r--r-- | platform/ios/src/MGLAccountManager.m | 14 | ||||
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 62 | ||||
-rw-r--r-- | platform/ios/src/MGLMapboxEvents.h | 5 | ||||
-rw-r--r-- | platform/ios/src/MGLMapboxEvents.m | 66 |
4 files changed, 97 insertions, 50 deletions
diff --git a/platform/ios/src/MGLAccountManager.m b/platform/ios/src/MGLAccountManager.m index 8bfe1d68b3..c5aeae7077 100644 --- a/platform/ios/src/MGLAccountManager.m +++ b/platform/ios/src/MGLAccountManager.m @@ -8,7 +8,6 @@ @interface MGLAccountManager() <FABKit> -@property (atomic) BOOL mapboxMetricsEnabledSettingShownInApp; @property (atomic) NSString *accessToken; @end @@ -21,15 +20,8 @@ // Load all referenced categories due to absence of -ObjC linker flag [MGLCategoryLoader loadCategories]; - // Read the initial configuration from Info.plist. The shown-in-app setting - // preempts the Settings bundle check in -[MGLMapboxEvents init] triggered - // by setting the access token. - NSBundle *bundle = [NSBundle mainBundle]; - NSNumber *shownInAppNumber = [bundle objectForInfoDictionaryKey:@"MGLMapboxMetricsEnabledSettingShownInApp"]; - if (shownInAppNumber) { - [MGLAccountManager sharedManager].mapboxMetricsEnabledSettingShownInApp = [shownInAppNumber boolValue]; - } - NSString *accessToken = [bundle objectForInfoDictionaryKey:@"MGLMapboxAccessToken"]; + // Read the initial configuration from Info.plist. + NSString *accessToken = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MGLMapboxAccessToken"]; if (accessToken.length) { self.accessToken = accessToken; } @@ -60,7 +52,7 @@ } + (BOOL) mapboxMetricsEnabledSettingShownInApp { - return [MGLAccountManager sharedManager].mapboxMetricsEnabledSettingShownInApp; + NSLog(@"mapboxMetricsEnabledSettingShownInApp is no longer necessary; the Mapbox iOS SDK has changed to always provide a telemetry setting in-app."); } + (void) setAccessToken:(NSString *) accessToken { diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 4ee12942b4..0fdf2ea66a 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -117,6 +117,7 @@ public: CLLocationManagerDelegate, UIActionSheetDelegate, MGLCalloutViewDelegate, + UIAlertViewDelegate, MGLMultiPointDelegate, MGLAnnotationImageDelegate> @@ -333,6 +334,7 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration) _attributionButton.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:_attributionButton]; _attributionButtonConstraints = [NSMutableArray array]; + [_attributionButton addObserver:self forKeyPath:@"hidden" options:NSKeyValueObservingOptionNew context:NULL]; // setup compass // @@ -480,6 +482,7 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration) { [[NSNotificationCenter defaultCenter] removeObserver:self]; [[MGLAccountManager sharedManager] removeObserver:self forKeyPath:@"accessToken"]; + [_attributionButton removeObserver:self forKeyPath:@"hidden"]; [self validateDisplayLink]; @@ -1422,13 +1425,9 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration) @"© Mapbox", @"© OpenStreetMap", @"Improve This Map", + @"Mapbox Telemetry", nil]; - // iOS 8+: add action that opens app's Settings.app panel, if applicable - if (&UIApplicationOpenSettingsURLString != NULL && ! [MGLAccountManager mapboxMetricsEnabledSettingShownInApp]) - { - [self.attributionSheet addButtonWithTitle:@"Adjust Privacy Settings"]; - } } [self.attributionSheet showFromRect:self.attributionButton.frame inView:self animated:YES]; @@ -1453,10 +1452,48 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration) [[UIApplication sharedApplication] openURL: [NSURL URLWithString:feedbackURL]]; } - // skips to 4 because button is conditionally added after cancel (index 3) - else if (buttonIndex == actionSheet.firstOtherButtonIndex + 4) + else if (buttonIndex == actionSheet.firstOtherButtonIndex + 3) { - [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; + NSString *message; + NSString *participate; + NSString *optOut; + + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"MGLMapboxMetricsEnabled"]) + { + message = @"You are helping to make OpenStreetMap and Mapbox maps better by contributing anonymous usage data."; + participate = @"Keep Participating"; + optOut = @"Stop Participating"; + } + else + { + message = @"You can help make OpenStreetMap and Mapbox maps better by contributing anonymous usage data."; + participate = @"Participate"; + optOut = @"Don’t Participate"; + } + + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Make Mapbox Maps Better" + message:message + delegate:self + cancelButtonTitle:participate + otherButtonTitles:@"Tell Me More", optOut, nil]; + [alert show]; + } +} + +- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex +{ + if (buttonIndex == alertView.cancelButtonIndex) + { + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"MGLMapboxMetricsEnabled"]; + } + else if (buttonIndex == alertView.firstOtherButtonIndex) + { + [[UIApplication sharedApplication] openURL: + [NSURL URLWithString:@"https://mapbox.com/telemetry/"]]; + } + else if (buttonIndex == alertView.firstOtherButtonIndex + 1) + { + [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"MGLMapboxMetricsEnabled"]; } } @@ -1472,6 +1509,15 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration) _mbglFileSource->setAccessToken((std::string)[accessToken UTF8String]); } } + else if ([keyPath isEqualToString:@"hidden"] && object == _attributionButton) + { + NSNumber *hiddenNumber = change[NSKeyValueChangeNewKey]; + BOOL attributionButtonWasHidden = [hiddenNumber boolValue]; + if (attributionButtonWasHidden) + { + [MGLMapboxEvents ensureMetricsOptoutExists]; + } + } } + (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingZoomEnabled diff --git a/platform/ios/src/MGLMapboxEvents.h b/platform/ios/src/MGLMapboxEvents.h index 920a2227fd..dba24885bf 100644 --- a/platform/ios/src/MGLMapboxEvents.h +++ b/platform/ios/src/MGLMapboxEvents.h @@ -66,7 +66,10 @@ typedef NS_MUTABLE_DICTIONARY_OF(NSString *, id) MGLMutableMapboxEventAttributes + (void) flush; // Main thread only -+ (void)validate; ++ (void) validate; + +// Main thread only ++ (void) ensureMetricsOptoutExists; @end diff --git a/platform/ios/src/MGLMapboxEvents.m b/platform/ios/src/MGLMapboxEvents.m index 259cfb3def..5fc062a2a2 100644 --- a/platform/ios/src/MGLMapboxEvents.m +++ b/platform/ios/src/MGLMapboxEvents.m @@ -180,36 +180,6 @@ const NSTimeInterval MGLFlushInterval = 60; self = [super init]; if (self) { - if (! [MGLAccountManager mapboxMetricsEnabledSettingShownInApp] && - [[NSUserDefaults standardUserDefaults] integerForKey:@"MGLMapboxAccountType"] == 0) { - // Opt Out is not configured in UI, so check for Settings.bundle - // Put Settings bundle into memory - id defaultEnabledValue; - NSString *appSettingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"]; - - if (appSettingsBundle) { - // Dynamic Settings.bundle loading based on: - // http://stackoverflow.com/questions/510216/can-you-make-the-settings-in-settings-bundle-default-even-if-you-dont-open-the - NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[appSettingsBundle stringByAppendingPathComponent:@"Root.plist"]]; - NSArray *preferences = settings[@"PreferenceSpecifiers"]; - for (NSDictionary *prefSpecification in preferences) { - if ([prefSpecification[@"Key"] isEqualToString:@"MGLMapboxMetricsEnabled"]) { - defaultEnabledValue = prefSpecification[@"DefaultValue"]; - } - } - } - - if (!defaultEnabledValue) - { - [NSException raise:@"MGLMapboxMetricsEnabled setting missing" format: - @"End users must be able to opt out of Metrics in your app, either inside Settings (via Settings.bundle) or inside this app. " - @"If you implement the opt-out control inside this app, disable this assertion by setting MGLMapboxMetricsEnabledSettingShownInApp to YES in Info.plist."]; - } - [[NSUserDefaults standardUserDefaults] registerDefaults:@{ - @"MGLMapboxMetricsEnabled": defaultEnabledValue, - }]; - } - _appBundleId = [[NSBundle mainBundle] bundleIdentifier]; _appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]; _appVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; @@ -770,6 +740,42 @@ const NSTimeInterval MGLFlushInterval = 60; return result; } +// Main thread only +// ++ (void) ensureMetricsOptoutExists { + MGLAssertIsMainThread(); + + NSNumber *shownInAppNumber = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MGLMapboxMetricsEnabledSettingShownInApp"]; + BOOL metricsEnabledSettingShownInAppFlag = [shownInAppNumber boolValue]; + + if ( ! metricsEnabledSettingShownInAppFlag && + [[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"]; + + if (appSettingsBundle) { + // Dynamic Settings.bundle loading based on http://stackoverflow.com/a/510329/2094275 + NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[appSettingsBundle stringByAppendingPathComponent:@"Root.plist"]]; + NSArray *preferences = settings[@"PreferenceSpecifiers"]; + for (NSDictionary *prefSpecification in preferences) { + if ([prefSpecification[@"Key"] isEqualToString:@"MGLMapboxMetricsEnabled"]) { + defaultEnabledValue = prefSpecification[@"DefaultValue"]; + } + } + } + + if ( ! defaultEnabledValue) { + [NSException raise:@"Telemetry opt-out missing" format: + @"End users must be able to opt out of Mapbox Telemetry in your app, either inside Settings (via Settings.bundle) or inside this app. " + @"By default, this opt-out control is included as a menu item in the attribution action sheet. " + @"If you reimplement the opt-out control inside this app, disable this assertion by setting MGLMapboxMetricsEnabledSettingShownInApp to YES in Info.plist." + @"\n\nSee https://www.mapbox.com/ios-sdk/#telemetry_opt_out for more information." + @"\n\nAdditionally, by hiding this attribution control you agree to display the required attribution elsewhere in this app."]; + } + } +} + #pragma mark CLLocationManagerDelegate - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { // Iterate through locations to pass all data |