RNPermissionHandlerLocationAlways.m 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #import "RNPermissionHandlerLocationAlways.h"
  2. @import CoreLocation;
  3. @import UIKit;
  4. @interface RNPermissionHandlerLocationAlways() <CLLocationManagerDelegate>
  5. @property (nonatomic, strong) CLLocationManager *locationManager;
  6. @property (nonatomic) bool initialChangeEventFired;
  7. @property (nonatomic) bool isWaitingDidBecomeActive;
  8. @property (nonatomic, strong) void (^resolve)(RNPermissionStatus status);
  9. @property (nonatomic, strong) void (^reject)(NSError *error);
  10. @end
  11. @implementation RNPermissionHandlerLocationAlways
  12. + (NSArray<NSString *> * _Nonnull)usageDescriptionKeys {
  13. return @[
  14. @"NSLocationAlwaysAndWhenInUseUsageDescription",
  15. @"NSLocationAlwaysUsageDescription",
  16. @"NSLocationWhenInUseUsageDescription",
  17. ];
  18. }
  19. + (NSString * _Nonnull)handlerUniqueId {
  20. return @"ios.permission.LOCATION_ALWAYS";
  21. }
  22. - (void)checkWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
  23. rejecter:(void (__unused ^ _Nonnull)(NSError * _Nonnull))reject {
  24. if (![CLLocationManager locationServicesEnabled] || ![RNPermissions isBackgroundModeEnabled:@"location"]) {
  25. return resolve(RNPermissionStatusNotAvailable);
  26. }
  27. switch ([CLLocationManager authorizationStatus]) {
  28. case kCLAuthorizationStatusNotDetermined:
  29. return resolve(RNPermissionStatusNotDetermined);
  30. case kCLAuthorizationStatusRestricted:
  31. return resolve(RNPermissionStatusRestricted);
  32. case kCLAuthorizationStatusAuthorizedWhenInUse:
  33. case kCLAuthorizationStatusDenied:
  34. return resolve(RNPermissionStatusDenied);
  35. case kCLAuthorizationStatusAuthorizedAlways:
  36. return resolve(RNPermissionStatusAuthorized);
  37. }
  38. }
  39. - (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
  40. rejecter:(void (^ _Nonnull)(NSError * _Nonnull))reject {
  41. if (![CLLocationManager locationServicesEnabled] || ![RNPermissions isBackgroundModeEnabled:@"location"]) {
  42. return resolve(RNPermissionStatusNotAvailable);
  43. }
  44. CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
  45. if (status == kCLAuthorizationStatusAuthorizedAlways) {
  46. return resolve(RNPermissionStatusAuthorized);
  47. }
  48. _resolve = resolve;
  49. _reject = reject;
  50. _initialChangeEventFired = false;
  51. _isWaitingDidBecomeActive = false;
  52. if (status == kCLAuthorizationStatusAuthorizedWhenInUse && ![RNPermissions isFlaggedAsRequested:[[self class] handlerUniqueId]]) {
  53. _isWaitingDidBecomeActive = true;
  54. [[NSNotificationCenter defaultCenter] addObserver:self
  55. selector:@selector(UIApplicationDidBecomeActiveNotification:)
  56. name:UIApplicationDidBecomeActiveNotification object:nil];
  57. }
  58. _locationManager = [CLLocationManager new];
  59. [_locationManager setDelegate:self];
  60. [_locationManager requestAlwaysAuthorization];
  61. }
  62. - (void)onAuthorizationStatus {
  63. [RNPermissions flagAsRequested:[[self class] handlerUniqueId]];
  64. [self checkWithResolver:_resolve rejecter:_reject];
  65. [_locationManager setDelegate:nil];
  66. _locationManager = nil;
  67. if (_isWaitingDidBecomeActive) {
  68. [[NSNotificationCenter defaultCenter] removeObserver:self
  69. name:UIApplicationDidBecomeActiveNotification
  70. object:nil];
  71. }
  72. }
  73. - (void)UIApplicationDidBecomeActiveNotification:(NSNotification *)notification {
  74. if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse) {
  75. [self onAuthorizationStatus];
  76. }
  77. }
  78. - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
  79. // @see https://github.com/iosphere/ISHPermissionKit/blob/2.1.2/ISHPermissionKit/Requests/ISHPermissionRequestLocation.m#L127
  80. if (status != kCLAuthorizationStatusNotDetermined && _initialChangeEventFired) {
  81. [self onAuthorizationStatus];
  82. } else {
  83. _initialChangeEventFired = true;
  84. }
  85. }
  86. @end