RNPermissionHandlerLocationAlways.m 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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 hasAlreadyBeenRequested:self]) {
  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. [self checkWithResolver:_resolve rejecter:_reject];
  64. [_locationManager setDelegate:nil];
  65. _locationManager = nil;
  66. if (_isWaitingDidBecomeActive) {
  67. [[NSNotificationCenter defaultCenter] removeObserver:self
  68. name:UIApplicationDidBecomeActiveNotification
  69. object:nil];
  70. }
  71. }
  72. - (void)UIApplicationDidBecomeActiveNotification:(NSNotification *)notification {
  73. if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse) {
  74. [self onAuthorizationStatus];
  75. }
  76. }
  77. - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
  78. // @see https://github.com/iosphere/ISHPermissionKit/blob/2.1.2/ISHPermissionKit/Requests/ISHPermissionRequestLocation.m#L127
  79. if (status != kCLAuthorizationStatusNotDetermined && _initialChangeEventFired) {
  80. [self onAuthorizationStatus];
  81. } else {
  82. _initialChangeEventFired = true;
  83. }
  84. }
  85. @end