Skip to content

Managing Privacy Alerts: Location Services, APNS, Contacts (Deprecated)

Joshua Moody edited this page Nov 14, 2019 · 1 revision

NOTICE

This document concerns testing under UIAutomation which has been deprecated for several years.

Calabash and Xamarin.UITest now use DeviceAgent for automation. DeviceAgent automation is not blocked by SpringBoard alerts.

The advice about following the HIG is useful, so I will not remove the existing content.

UIAutomation

These are alerts are generated by the OS to control an app's access to Apple Push Notifications, Location, Services, a user's Contacts, and hardware features (e.g. Microphone and Camera).

Calabash attempts to dismiss these alerts when they appear because they are often very difficult to interact with. For example, the iOS 8 UIAutomation API is broken; you cannot touch all buttons on these alerts using UIAutomation. Further, the way these alerts are handled varies across iOS versions (iOS 5 is dramatically different from iOS 6 and so on).

Alerts Can Block Instruments

One problem that we see often is that this kind of UIAlertView appears before Instruments can take control of the app. As a result, the UIAutomation cannot dismiss the alert and the application hangs.

In some cases, applications that ask for location services, access to contacts, access to photos, etc, are violating the Mobile HIG guidelines.

In some sense we consider this a feature of Calabash - it is exposing a potential problem (a HIG violation) in apps.

from the HIG

Ask permission at app startup only if your app can't perform its primary function without the user's data.

People will not be bothered by this if it's obvious that the main function of your app depends on knowing their personal information.

Avoid making programmatic calls that trigger the alert before the user actually selects the feature that needs the data.

This way, you avoid causing people to wonder why your app wants their personal information when they're doing something that doesn't appear to need it.

For location data, check the Location Services preference to avoid triggering the alert unnecessarily.

Workaround: Add a delay.

If your app's primary function cannot be achieved without access to Location, Contacts, Photos, etc. then consider add a small delay before triggering these alerts.

If this is not acceptable in your production app, then consider using a compiler macro that confines the delay for the *-cal target.

The following code sample is from a real app.

    BOOL calabashBuild;
#ifdef CALABASH
    calabashBuild = YES;
#else
    calabashBuild = NO;
#endif

    __weak typeof(self) wself = self;
    dispatch_time_t delay;
    if (calabashBuild) {
      delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4.0 * NSEC_PER_SEC));
    } else {
      delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC));
    }
    dispatch_after(delay, dispatch_get_main_queue(), ^{
      SEL authorizationSelector = @selector(requestWhenInUseAuthorization);
      if ([wself.locationManager respondsToSelector:authorizationSelector]) {
        [wself.locationManager requestWhenInUseAuthorization];
      } else {
        if ([CLLocationManager locationServicesEnabled]) {
          [wself.locationManager startUpdatingLocation];
          self.showsUserLocation = YES;
        }
      }
    });
Clone this wiki locally