Dodaj CLLocationManagerDelegate
do dziedziczenia swojej klasy, a następnie możesz dokonać tego sprawdzenia:
Wersja Swift 1.x - 2.x:
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")
}
Wersja Swift 4.x:
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")
}
Wersja Swift 5.1
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")
}
manager.locationServicesEnabled()
ZamiastCLLocationManager.loationServicesEnabled()
Solved!authorizationStatus
jest ustawiony nanotDetermined
to zamiast po prostu rejestrować, lepiej zapytać użytkownika „Zezwól / Nie zezwalaj”W celu-c
Powinieneś śledzić użytkownika, któremu już odmówiono lub nie został określony, a następnie poprosić o pozwolenie lub wysłać użytkownika do aplikacji Setting.
-(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]; } }
Zaimplementuj delegata alertView, a następnie wysłał użytkownika, aby włączyć usługę lokalizacji, jeśli została już odrzucona przez użytkownika.
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (alertView.tag == 199) { if (buttonIndex == 1) { [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; } return; } }
Uruchom Menedżera lokalizacji
-(void)initLocationManager{ self.locationManager = [[CLLocationManager alloc] init]; if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { [self.locationManager requestAlwaysAuthorization]; } }
Należy pamiętać, że kCLAuthorizationStatusAuthorizedAlways i kCLAuthorizationStatusAuthorizedWhenInUse to różnica.
źródło
SWIFT (od 24 lipca 2018 r.)
if CLLocationManager.locationServicesEnabled() { }
Dzięki temu dowiesz się, czy użytkownik wybrał już ustawienie dla żądania pozwolenia na lokalizację w aplikacji
źródło
W Swift 4 to tylko funkcja 2-liniowa:
import CoreLocation static func isLocationPermissionGranted() -> Bool { guard CLLocationManager.locationServicesEnabled() else { return false } return [.authorizedAlways, .authorizedWhenInUse].contains(CLLocationManager.authorizationStatus()) }
źródło
Oto format zalecany przez Apple .
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 }
Oto pełny przykład.
Obejmuje to
AlertView
przycisk z przyciskiem przenoszącym użytkownika doSettings
ekranu, jeśli wcześniej odmówiono mu dostępu.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 } } } }
źródło
Dla swift3.0 i nowszych, jeśli często sprawdzane są dostępność usług lokalizacyjnych, utwórz klasę jak poniżej,
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 } } }
a następnie użyj go w ten sposób w swoim 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) } }
źródło
Gdy wywołasz -startLocation, jeśli usługi lokalizacyjne zostały odrzucone przez użytkownika, delegat menedżera lokalizacji otrzyma wywołanie -
locationManager:didFailWithError
: zkCLErrorDenied
kodem błędu. Działa to zarówno we wszystkich wersjach iOS.źródło
Use of unresolved identifier 'kCLErrorDenied'
. Myśli?W 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 }
źródło
Aby poprosić o pozwolenie na korzystanie z usług lokalizacyjnych, z których korzystasz:
Jeśli stan jest obecnie nieokreślony, pojawi się alert z monitem o zezwolenie na dostęp. W przypadku odmowy dostępu Twoja aplikacja zostanie powiadomiona w CLLocationManagerDelegate, podobnie jak w przypadku odmowy pozwolenia w dowolnym momencie zostaniesz zaktualizowany tutaj.
Istnieją dwa odrębne stany, które należy sprawdzić, aby określić bieżące uprawnienia.
CLLocationManager.locationServicesEnabled()
CLLocationManager.authorizationStatus() == .authorizedWhenInUse
Możesz dodać rozszerzenie to przydatna opcja:
extension CLLocationManager { static func authorizedToRequestLocation() -> Bool { return CLLocationManager.locationServicesEnabled() && (CLLocationManager.authorizationStatus() == .authorizedAlways || CLLocationManager.authorizationStatus() == .authorizedWhenInUse) }
}
Tutaj jest dostępny, gdy użytkownik najpierw poprosił o wskazówki:
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) } }
Oto delegat:
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { if !CLLocationManager.authorizedToRequestLocation() { showAlertNoLocation(locationError: .invalidPermissions) } }
źródło