Ich habe einige Nachforschungen über CoreLocation angestellt. Vor kurzem bin ich auf ein Problem gestoßen, das an anderer Stelle behandelt wurde, jedoch in Objective C und für iOS 8.
Ich finde es irgendwie albern, das zu fragen, 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 locationServicesEnabled()
verwenden, aber das scheint beim Kompilieren für iOS 9 nicht zu funktionieren.
Wie würde ich das erreichen?
Vielen Dank!
Fügen Sie das CLLocationManagerDelegate
zu Ihrer Klassenvererbung hinzu, und dann können Sie Folgendes überprüfen:
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")
}
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")
}
In Ziel-c
sie sollten den Benutzer verfolgen, der bereits abgelehnt oder nicht bestimmt wurde, 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 dann den Benutzer, um den Standortdienst zu aktivieren, wenn der Benutzer dies bereits verweigert hat.
-(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 kCLAuthorizationStatusAuthorizedAlways und kCLAuthorizationStatusAuthorizedWhenInUse ist der Unterschied.
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
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())
}
Erstellen Sie für Swift3.0 und höher eine Klasse wie folgt, wenn die Verfügbarkeit von Ortungsdiensten häufig überprüft wird:
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 benutze es dann so in deiner 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)
}
}
Hier ist das Format Apple empfohlen.
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
}
}
Dies beinhaltet ein AlertView
mit einer Schaltfläche, um den Benutzer zum Bildschirm Settings
zu führen, 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
}
}
}
}
Wenn Sie -startLocation aufrufen und die Standortdienste vom Benutzer abgelehnt wurden, erhält der Standortmanager-Delegat einen Anruf an - locationManager:didFailWithError
: mit dem kCLErrorDenied
Fehlercode. Dies funktioniert in allen Versionen von iOS.
In Swift 3.
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
}
So bitten Sie um Erlaubnis für die von Ihnen verwendeten Ortungsdienste:
yourSharedLocationManager.requestWhenInUseAuthorization()
Wenn der Status derzeit unbestimmt ist, wird eine Warnung angezeigt, die den Benutzer auffordert, den Zugriff zuzulassen. Wenn der Zugriff verweigert wird, wird Ihre App im CLLocationManagerDelegate benachrichtigt. Wenn die Berechtigung verweigert wird, werden Sie hier ebenfalls aktualisiert.
Es gibt zwei separate Status, die Sie überprüfen müssen, um die aktuellen Berechtigungen zu ermitteln.
CLLocationManager.locationServicesEnabled()
CLLocationManager.authorizationStatus() == .authorizedWhenInUse
Sie könnten eine Erweiterung hinzufügen, dies ist eine praktische Option:
extension CLLocationManager {
static func authorizedToRequestLocation() -> Bool {
return CLLocationManager.locationServicesEnabled() &&
(CLLocationManager.authorizationStatus() == .authorizedAlways || CLLocationManager.authorizationStatus() == .authorizedWhenInUse)
}
}
Hier wird 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)
}
}