Überprüfen Sie, ob Ortungsdienste aktiviert sind

87

Ich habe einige Nachforschungen über CoreLocation angestellt. Vor kurzem bin ich auf ein Problem gestoßen, das an anderer Stelle behandelt wurde, jedoch in Ziel C und für iOS 8.

Ich bin ein bisschen albern, wenn ich das frage, aber wie können Sie überprüfen, ob Ortungsdienste mit Swift unter iOS 9 aktiviert sind?

Unter iOS 7 (und vielleicht 8?) Könnten Sie verwenden locationServicesEnabled(), aber das scheint beim Kompilieren für iOS 9 nicht zu funktionieren.

Wie würde ich das erreichen?

Vielen Dank!

Brendan Chang
quelle

Antworten:

240

Fügen Sie das CLLocationManagerDelegatezu Ihrer Klassenvererbung hinzu, und dann können Sie folgende Prüfung durchführen:

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")
}
Rashwan L.
quelle
8
Jep! Vielen Dank! Mein Problem war, dass ich versuchte, locatoinServicesEnabled auf meinem Manager aufzurufen, dh manager.locationServicesEnabled() nicht CLLocationManager.loationServicesEnabled() gelöst!
Brendan Chang
2
Ich bekomme es , dass Ihr Code ist nur ein Beispiel, aber es ist etwas irreführend ... Ich denke , es ist besser, wenn authorizationStatuswird eingestellt , um notDetermineddann statt nur Protokollierung es besser wäre , den Benutzer aufzufordern , ‚Zulassen / nicht zulassen“
Honig
@Honey, sicher können Sie es natürlich verwenden, wie Sie es bevorzugen, und wie Sie sagten, ist der Code nur ein Beispiel, um zu zeigen, wie es verwendet werden könnte.
Rashwan L
13

In Ziel-c

Sie sollten den bereits abgelehnten oder nicht bestimmten Benutzer verfolgen und dann um Erlaubnis bitten oder den Benutzer an die Einstellungs-App senden.

-(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];
   }

}

Implementieren Sie alertView Delegate und senden Sie den Benutzer, um den Standortdienst zu aktivieren, wenn er vom Benutzer bereits abgelehnt wurde.

-(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];
   }
}

Bitte beachten Sie, dass kCLAuthorizationStatusAuthorizedAlways und kCLAuthorizationStatusAuthorizedWhenInUse ein Unterschied sind.

Marosdee Uma
quelle
Vielen Dank für diese Objective-C-Version, obwohl die ursprüngliche Frage schnell war. Zusätzliche Hinweise: Rufen Sie requestWhenInUseAuthorization auf, wenn der Status nicht ermittelt wurde, setzen Sie den entsprechenden Plist-Eintrag für die Verwendungsbeschreibung (möglicherweise lokalisiert) und implementieren Sie möglicherweise didChangeAuthorizationStatus
Giorgio Barchiesi
9

SWIFT (Stand 24. Juli 2018)

if CLLocationManager.locationServicesEnabled() {

}

Hier erfahren Sie, ob der Benutzer bereits eine Einstellung für die Standortberechtigungsanforderung der App ausgewählt hat

BennyTheNerd
quelle
8

Es ist nur eine 2-Zeilen-Funktion in Swift 4:

import CoreLocation

static func isLocationPermissionGranted() -> Bool
{
    guard CLLocationManager.locationServicesEnabled() else { return false }
    return [.authorizedAlways, .authorizedWhenInUse].contains(CLLocationManager.authorizationStatus())
}
Suat KARAKUSOGLU
quelle
6

Hier ist das von Apple empfohlene Format .

  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
      }

Hier ist ein vollständiges Beispiel.

Dies beinhaltet AlertVieweine Schaltfläche, mit der der Benutzer zum SettingsBildschirm weitergeleitet werden kann, wenn ihm zuvor der Zugriff verweigert wurde.

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
            }
        }
    }
}
fs_tigre
quelle
5

Erstellen Sie für swift3.0 und höher eine Klasse wie unten, wenn häufige Überprüfungen der Verfügbarkeit von Ortungsdiensten durchgeführt werden.

    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
              }
            }
         }

und dann verwenden Sie es so in Ihrem 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)
        }
    }
Sri Hari YS
quelle
3

Wenn Sie -startLocation aufrufen und der Benutzer die Standortdienste verweigert, erhält der Standortmanager-Delegat einen Anruf an - locationManager:didFailWithError: mit dem kCLErrorDeniedFehlercode. Dies funktioniert in allen Versionen von iOS.

Shaheen Sharifian
quelle
Vielen Dank. Als ich das versuchte, zeigte es leider : Use of unresolved identifier 'kCLErrorDenied'. Gedanken?
Brendan Chang
1

In Swift 3.0

if (CLLocationManager.locationServicesEnabled())
            {
                locationManager.delegate = self
                locationManager.desiredAccuracy = kCLLocationAccuracyBest
                if ((UIDevice.current.systemVersion as NSString).floatValue >= 8)
                {
                    locationManager.requestWhenInUseAuthorization()
                }

                locationManager.startUpdatingLocation()
            }
            else
            {
                #if debug
                    println("Location services are not enabled");
                #endif
            }
Amul4608
quelle
1

So bitten Sie um Erlaubnis für von Ihnen verwendete Ortungsdienste:

yourSharedLocationManager.requestWhenInUseAuthorization()

Wenn der Status derzeit unbestimmt ist, wird eine Warnung angezeigt, in der der Benutzer aufgefordert wird, den Zugriff zuzulassen. Wenn der Zugriff verweigert wird, wird Ihre App im CLLocationManagerDelegate benachrichtigt. Wenn die Berechtigung zu irgendeinem Zeitpunkt verweigert wird, werden Sie hier aktualisiert.

Es gibt zwei separate Status, die Sie überprüfen müssen, um die aktuellen Berechtigungen zu ermitteln.

  • Wenn der Benutzer die allgemeinen Ortungsdienste aktiviert hat oder nicht

CLLocationManager.locationServicesEnabled()

  • Wenn der Benutzer die richtige Berechtigung für Ihre App erteilt hat.

CLLocationManager.authorizationStatus() == .authorizedWhenInUse

Sie können eine Erweiterung hinzufügen, eine praktische Option:

extension CLLocationManager {
static func authorizedToRequestLocation() -> Bool {
    return CLLocationManager.locationServicesEnabled() &&
        (CLLocationManager.authorizationStatus() == .authorizedAlways || CLLocationManager.authorizationStatus() == .authorizedWhenInUse)
}

}}

Hier wird darauf zugegriffen, wenn der Benutzer zum ersten Mal eine Wegbeschreibung angefordert hat:

 private func requestUserLocation() {
    //when status is not determined this method runs to request location access
    locationManager.requestWhenInUseAuthorization()

    if CLLocationManager.authorizedToRequestLocation() {

        //have accuracy set to best for navigation - accuracy is not guaranteed it 'does it's best'
        locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation

        //find out current location, using this one time request location will start the location services and then stop once have the location within the desired accuracy -
        locationManager.requestLocation()
    } else {
        //show alert for no location permission
        showAlertNoLocation(locationError: .invalidPermissions)
    }
}

Hier ist der Delegierte:

 func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {

    if !CLLocationManager.authorizedToRequestLocation() {
        showAlertNoLocation(locationError: .invalidPermissions)
    }
}
Jess
quelle