Check if location services are enabled

前端 未结 9 1659
情话喂你
情话喂你 2020-12-02 08:34

I\'ve been doing some research about CoreLocation. Recently, I encountered a problem that has been covered elsewhere, but in Objective C, and for iOS 8.

I feel kinda

相关标签:
9条回答
  • 2020-12-02 09:12

    For swift3.0 and above , if frequent checks are made for the availability of location services, create a class like below,

        import CoreLocation
    
        open class Reachability {
            class func isLocationServiceEnabled() -> Bool {
                if CLLocationManager.locationServicesEnabled() {
                    switch(CLLocationManager.authorizationStatus()) {
                        case .notDetermined, .restricted, .denied:
                        return false
                        case .authorizedAlways, .authorizedWhenInUse:
                        return true
                        default:
                        print("Something wrong with Location services")
                        return false
                    }
                } else {
                        print("Location services are not enabled")
                        return false
                  }
                }
             }
    

    and then use it like this in your VC

        if Reachability.isLocationServiceEnabled() == true {
        // Do what you want to do.
        } else {
        //You could show an alert like this.
            let alertController = UIAlertController(title: "Location 
            Services Disabled", message: "Please enable location services 
            for this app.", preferredStyle: .alert)
            let OKAction = UIAlertAction(title: "OK", style: .default, 
            handler: nil)
            alertController.addAction(OKAction)
            OperationQueue.main.addOperation {
                self.present(alertController, animated: true, 
                completion:nil)
            }
        }
    
    0 讨论(0)
  • 2020-12-02 09:18

    In objective-c

    you should track user already denied or not determined then ask for permission or sent user to Setting app.

    -(void)askEnableLocationService
    {
       BOOL showAlertSetting = false;
       BOOL showInitLocation = false;
    
       if ([CLLocationManager locationServicesEnabled]) {
    
          switch ([CLLocationManager authorizationStatus]) {
            case kCLAuthorizationStatusDenied:
                showAlertSetting = true;
                NSLog(@"HH: kCLAuthorizationStatusDenied");
                break;
            case kCLAuthorizationStatusRestricted:
                showAlertSetting = true;
                NSLog(@"HH: kCLAuthorizationStatusRestricted");
                break;
            case kCLAuthorizationStatusAuthorizedAlways:
                showInitLocation = true;
                NSLog(@"HH: kCLAuthorizationStatusAuthorizedAlways");
                break;
            case kCLAuthorizationStatusAuthorizedWhenInUse:
                showInitLocation = true;
                NSLog(@"HH: kCLAuthorizationStatusAuthorizedWhenInUse");
                break;
            case kCLAuthorizationStatusNotDetermined:
                showInitLocation = true;
                NSLog(@"HH: kCLAuthorizationStatusNotDetermined");
                break;
            default:
                break;
          }
       } else {
    
          showAlertSetting = true;
          NSLog(@"HH: locationServicesDisabled");
      }
    
       if (showAlertSetting) {
           UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"Please enable location service for this app in ALLOW LOCATION ACCESS: Always, Go to Setting?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Open Setting", nil];
           alertView.tag = 199;
           [alertView show];
       }
       if (showInitLocation) {
           [self initLocationManager];
       }
    
    }
    

    Implement alertView Delegate then sent user to enable location service if already deny by user.

    -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
    {
    
       if (alertView.tag == 199) {
           if (buttonIndex == 1) {
               [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
           }
           return;
       }
    }
    

    Init Location Manager

    -(void)initLocationManager{
       self.locationManager = [[CLLocationManager alloc] init];
       if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
           [self.locationManager requestAlwaysAuthorization];
       }
    }
    

    Please note kCLAuthorizationStatusAuthorizedAlways and kCLAuthorizationStatusAuthorizedWhenInUse is difference.

    0 讨论(0)
  • 2020-12-02 09:20

    When you call -startLocation, if location services were denied by the user, the location manager delegate will receive a call to - locationManager:didFailWithError: with the kCLErrorDenied error code. This works both in all versions of iOS.

    0 讨论(0)
  • 2020-12-02 09:21

    Add the CLLocationManagerDelegate to your class inheritance and then you can make this check:

    Swift 1.x - 2.x version:

    if CLLocationManager.locationServicesEnabled() {
        switch CLLocationManager.authorizationStatus() {
        case .NotDetermined, .Restricted, .Denied:
            print("No access")
        case .AuthorizedAlways, .AuthorizedWhenInUse:
            print("Access")
        }
    } else {
        print("Location services are not enabled")
    }
    

    Swift 4.x version:

    if CLLocationManager.locationServicesEnabled() {
         switch CLLocationManager.authorizationStatus() {
            case .notDetermined, .restricted, .denied:
                print("No access")
            case .authorizedAlways, .authorizedWhenInUse:
                print("Access")
            }
        } else {
            print("Location services are not enabled")
    }
    

    Swift 5.1 version

    if CLLocationManager.locationServicesEnabled() {
        switch CLLocationManager.authorizationStatus() {
            case .notDetermined, .restricted, .denied:
                print("No access")
            case .authorizedAlways, .authorizedWhenInUse:
                print("Access")
            @unknown default:
            break
        }
        } else {
            print("Location services are not enabled")
    }
    
    0 讨论(0)
  • 2020-12-02 09:21

    Here is the format Apple recommends.

      switch CLLocationManager.authorizationStatus() {
          case .notDetermined:
             // Request when-in-use authorization initially
             break
          case .restricted, .denied:
             // Disable location features
             break
          case .authorizedWhenInUse, .authorizedAlways:
             // Enable location features
             break
          }
    

    Here is a complete example.

    This includes an AlertView with a button to take the user to the Settings screen if previously denied access.

    import CoreLocation
    let locationManager = CLLocationManager()
    
    class SettingsTableViewController:CLLocationManagerDelegate{
    
        func checkUsersLocationServicesAuthorization(){
            /// Check if user has authorized Total Plus to use Location Services
            if CLLocationManager.locationServicesEnabled() {
                switch CLLocationManager.authorizationStatus() {
                case .notDetermined:
                    // Request when-in-use authorization initially
                    // This is the first and the ONLY time you will be able to ask the user for permission
                    self.locationManager.delegate = self
                    locationManager.requestWhenInUseAuthorization()
                    break
    
                case .restricted, .denied:
                    // Disable location features
                    switchAutoTaxDetection.isOn = false
                    let alert = UIAlertController(title: "Allow Location Access", message: "MyApp needs access to your location. Turn on Location Services in your device settings.", preferredStyle: UIAlertController.Style.alert)
    
                    // Button to Open Settings
                    alert.addAction(UIAlertAction(title: "Settings", style: UIAlertAction.Style.default, handler: { action in
                        guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
                            return
                        }
                        if UIApplication.shared.canOpenURL(settingsUrl) {
                            UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                                print("Settings opened: \(success)") 
                            })
                        }
                    }))
                    alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil))
                    self.present(alert, animated: true, completion: nil)
    
                    break
    
                case .authorizedWhenInUse, .authorizedAlways:
                    // Enable features that require location services here.
                    print("Full Access")
                    break
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-02 09:25

    It is just a 2 line function in Swift 4:

    import CoreLocation
    
    static func isLocationPermissionGranted() -> Bool
    {
        guard CLLocationManager.locationServicesEnabled() else { return false }
        return [.authorizedAlways, .authorizedWhenInUse].contains(CLLocationManager.authorizationStatus())
    }
    
    0 讨论(0)
提交回复
热议问题