Добавьте в CLLocationManagerDelegate
свой класс наследование, а затем вы можете выполнить эту проверку:
Версия 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")
}
Версия 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")
}
Версия 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()
вместо того, чтобыCLLocationManager.loationServicesEnabled()
решить!authorizationStatus
будет установлена наnotDetermined
то вместо того , чтобы просто войти было бы лучше , чтобы побудить пользователя «Разрешить / Не разрешать»В объекте-c
вы должны отслеживать пользователя, который уже отклонен или не определен, а затем запросить разрешение или отправить пользователя в приложение настройки.
-(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]; } }
Внедрите alertView Delegate, а затем отправьте пользователя для включения службы определения местоположения, если пользователь уже отказал.
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (alertView.tag == 199) { if (buttonIndex == 1) { [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; } return; } }
Инициировать диспетчер местоположения
-(void)initLocationManager{ self.locationManager = [[CLLocationManager alloc] init]; if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { [self.locationManager requestAlwaysAuthorization]; } }
Обратите внимание: kCLAuthorizationStatusAuthorizedAlways и kCLAuthorizationStatusAuthorizedWhenInUse - это разница.
источник
SWIFT (по состоянию на 24 июля 2018 г.)
if CLLocationManager.locationServicesEnabled() { }
это сообщит вам, если пользователь уже выбрал параметр для запроса разрешения местоположения приложения
источник
В Swift 4 это всего лишь двухстрочная функция:
import CoreLocation static func isLocationPermissionGranted() -> Bool { guard CLLocationManager.locationServicesEnabled() else { return false } return [.authorizedAlways, .authorizedWhenInUse].contains(CLLocationManager.authorizationStatus()) }
источник
Вот формат, который рекомендует 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 }
Вот полный пример.
Это включает в
AlertView
себя кнопку с кнопкой для вывода пользователя наSettings
экран, если ранее в доступе ему было отказано.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 } } } }
источник
Для swift3.0 и более поздних версий, если выполняются частые проверки доступности служб определения местоположения, создайте класс, как показано ниже,
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 } } }
а затем используйте это в своем 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) } }
источник
Когда вы вызываете -startLocation, если в службах определения местоположения пользователь отказал, делегат диспетчера местоположения получит вызов -
locationManager:didFailWithError
: сkCLErrorDenied
кодом ошибки. Это работает как во всех версиях iOS.источник
Use of unresolved identifier 'kCLErrorDenied'
. Мысли?В 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 }
источник
Чтобы запросить разрешение на службы определения местоположения, которые вы используете:
Если статус в настоящее время не определен, появится предупреждение, предлагающее пользователю разрешить доступ. Если в доступе будет отказано, ваше приложение будет уведомлено в CLLocationManagerDelegate, аналогично, если в разрешении будет отказано в любой момент, вы будете обновлены здесь.
Есть два отдельных статуса, которые необходимо проверить, чтобы определить текущие разрешения.
CLLocationManager.locationServicesEnabled()
CLLocationManager.authorizationStatus() == .authorizedWhenInUse
Вы можете добавить расширение - удобный вариант:
extension CLLocationManager { static func authorizedToRequestLocation() -> Bool { return CLLocationManager.locationServicesEnabled() && (CLLocationManager.authorizationStatus() == .authorizedAlways || CLLocationManager.authorizationStatus() == .authorizedWhenInUse) }
}
Здесь к нему обращаются, когда пользователь впервые запросил маршрут:
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) } }
Вот делегат:
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { if !CLLocationManager.authorizedToRequestLocation() { showAlertNoLocation(locationError: .invalidPermissions) } }
источник