123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. //
  2. // RNPLocation.m
  3. // ReactNativePermissions
  4. //
  5. // Created by Yonah Forst on 11/07/16.
  6. // Copyright © 2016 Yonah Forst. All rights reserved.
  7. //
  8. #import "RNPLocation.h"
  9. #import <CoreLocation/CoreLocation.h>
  10. @interface RNPLocation() <CLLocationManagerDelegate>
  11. @property (strong, nonatomic) CLLocationManager* locationManager;
  12. @property (copy) void (^completionHandler)(NSString *);
  13. @end
  14. @implementation RNPLocation
  15. + (NSString *)getStatusForType:(NSString *)type
  16. {
  17. if (![CLLocationManager locationServicesEnabled]) {
  18. return RNPStatusRestricted;
  19. }
  20. int status = [CLLocationManager authorizationStatus];
  21. switch (status) {
  22. case kCLAuthorizationStatusAuthorizedAlways:
  23. return RNPStatusAuthorized;
  24. case kCLAuthorizationStatusAuthorizedWhenInUse:
  25. return [type isEqualToString:@"always"] ? RNPStatusDenied : RNPStatusAuthorized;
  26. case kCLAuthorizationStatusDenied:
  27. return RNPStatusDenied;
  28. case kCLAuthorizationStatusRestricted:
  29. return RNPStatusRestricted;
  30. default:
  31. return RNPStatusUndetermined;
  32. }
  33. }
  34. - (void)request:(NSString*)type completionHandler:(void (^)(NSString *))completionHandler
  35. {
  36. if (![CLLocationManager locationServicesEnabled]) {
  37. return completionHandler(RNPStatusRestricted);
  38. }
  39. NSString *status = [RNPLocation getStatusForType:nil];
  40. if (status == RNPStatusUndetermined) {
  41. self.completionHandler = completionHandler;
  42. if (self.locationManager == nil) {
  43. self.locationManager = [[CLLocationManager alloc] init];
  44. self.locationManager.delegate = self;
  45. }
  46. if ([type isEqualToString:@"always"]) {
  47. [self.locationManager requestAlwaysAuthorization];
  48. } else {
  49. [self.locationManager requestWhenInUseAuthorization];
  50. }
  51. } else {
  52. if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse && [type isEqualToString:@"always"]) {
  53. completionHandler(RNPStatusDenied);
  54. } else {
  55. completionHandler(status);
  56. }
  57. }
  58. }
  59. -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
  60. if (status != kCLAuthorizationStatusNotDetermined) {
  61. if (self.locationManager) {
  62. self.locationManager.delegate = nil;
  63. self.locationManager = nil;
  64. }
  65. if (self.completionHandler) {
  66. //for some reason, checking permission right away returns denied. need to wait a tiny bit
  67. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
  68. self.completionHandler([RNPLocation getStatusForType:nil]);
  69. self.completionHandler = nil;
  70. });
  71. }
  72. }
  73. }
  74. @end