Skip to content

Commit

Permalink
feat(iOS): Configurable authorization level on iOS (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
tyronet-sportsbet authored and matt-oakes committed Apr 18, 2019
1 parent f7ce743 commit a9939cc
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ Sets configuration options that will be used in all location requests.
Supported options:

* `skipPermissionRequests` (boolean, iOS-only) - Defaults to `false`. If `true`, you must request permissions before using Geolocation APIs.
* `authorizationLevel` (string, iOS-only) - Either `"whenInUse"`, `"always"`, or `"auto"`. Changes the whether the user will be asked to give "always" or "when in use" location services permission. Any other value or `auto` will use the default behaviour, where the permission level is based on the contents of your `Info.plist`.

---

Expand Down
38 changes: 33 additions & 5 deletions ios/RNCGeolocation.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,17 @@ typedef NS_ENUM(NSInteger, RNCPositionErrorCode) {
RNCPositionErrorTimeout,
};

typedef NS_ENUM(NSInteger, RNCGeolocationAuthorizationLevel) {
RNCGeolocationAuthorizationLevelDefault,
RNCGeolocationAuthorizationLevelWhenInUse,
RNCGeolocationAuthorizationLevelAlways,
};

#define RNC_DEFAULT_LOCATION_ACCURACY kCLLocationAccuracyHundredMeters

typedef struct {
BOOL skipPermissionRequests;
RNCGeolocationAuthorizationLevel authorizationLevel;
} RNCGeolocationConfiguration;

typedef struct {
Expand All @@ -37,14 +44,22 @@ typedef NS_ENUM(NSInteger, RNCPositionErrorCode) {
BOOL useSignificantChanges;
} RNCGeolocationOptions;

@implementation RCTConvert (RNCGeolocationAuthorizationLevel)
RCT_ENUM_CONVERTER(RNCGeolocationAuthorizationLevel, (@{
@"whenInUse": @(RNCGeolocationAuthorizationLevelWhenInUse),
@"always": @(RNCGeolocationAuthorizationLevelAlways)}),
RNCGeolocationAuthorizationLevelDefault, integerValue)
@end

@implementation RCTConvert (RNCGeolocationOptions)

+ (RNCGeolocationConfiguration)RNCGeolocationConfiguration:(id)json
{
NSDictionary<NSString *, id> *options = [RCTConvert NSDictionary:json];

return (RNCGeolocationConfiguration) {
.skipPermissionRequests = [RCTConvert BOOL:options[@"skipPermissionRequests"]]
.skipPermissionRequests = [RCTConvert BOOL:options[@"skipPermissionRequests"]],
.authorizationLevel = [RCTConvert RNCGeolocationAuthorizationLevel:options[@"authorizationLevel"]]
};
}

Expand Down Expand Up @@ -202,10 +217,24 @@ - (void)timeout:(NSTimer *)timer
_locationManager = [CLLocationManager new];
_locationManager.delegate = self;
}
BOOL wantsAlways = NO;
BOOL wantsWhenInUse = NO;
if (_locationConfiguration.authorizationLevel == RNCGeolocationAuthorizationLevelDefault) {
if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"] &&
[_locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
wantsAlways = YES;
} else if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"] &&
[_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
wantsWhenInUse = YES;
}
} else if (_locationConfiguration.authorizationLevel == RNCGeolocationAuthorizationLevelAlways) {
wantsAlways = YES;
} else if (_locationConfiguration.authorizationLevel == RNCGeolocationAuthorizationLevelWhenInUse) {
wantsWhenInUse = YES;
}

// Request location access permission
if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"] &&
[_locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
if (wantsAlways) {
[_locationManager requestAlwaysAuthorization];

// On iOS 9+ we also need to enable background updates
Expand All @@ -215,8 +244,7 @@ - (void)timeout:(NSTimer *)timer
[_locationManager setAllowsBackgroundLocationUpdates:YES];
}
}
} else if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"] &&
[_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
} else if (wantsWhenInUse) {
[_locationManager requestWhenInUseAuthorization];
}
}
Expand Down
1 change: 1 addition & 0 deletions js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ let updatesEnabled = false;

type GeoConfiguration = {
skipPermissionRequests: boolean,
authorizationLevel: 'always' | 'whenInUse' | 'auto',
};

type GeoOptions = {
Expand Down
1 change: 1 addition & 0 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

export type GeolocationConfiguration = {
skipPermissionRequests: boolean;
authorizationLevel: 'always' | 'whenInUse' | 'auto';
};

export type GeolocationOptions = {
Expand Down

0 comments on commit a9939cc

Please sign in to comment.