Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable authorization level (iOS) #26

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"` or `"always"`. Changes the whether the user will be asked to give "always" or "when in use" location services permission. Any other value 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',
matt-oakes marked this conversation as resolved.
Show resolved Hide resolved
};

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"
matt-oakes marked this conversation as resolved.
Show resolved Hide resolved
};

export type GeolocationOptions = {
Expand Down