检查定位服务是否开启
Check if location services are enabled
我一直在研究 CoreLocation。最近,我遇到了一个在其他地方已经涵盖的问题,但是在 Objective C 和 iOS 8.
我觉得问这个问题有点傻,但是您如何在 iOS 9 上使用 swift 检查是否启用了定位服务?
在 iOS 7(也许是 8?)上,您可以使用 locationServicesEnabled()
,但在为 iOS 9.[=11= 编译时似乎不起作用]
那么我该如何完成呢?
谢谢!
当您调用 -startLocation 时,如果位置服务被用户拒绝,位置管理器委托将收到对 - locationManager:didFailWithError
的调用:带有 kCLErrorDenied
错误代码。这适用于 iOS.
的所有版本
将 CLLocationManagerDelegate
添加到您的 class 继承中,然后您可以进行此检查:
导入 CoreLocation 框架
import CoreLocation
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")
}
iOS 14.x
在 iOS 14 中,您将收到以下错误消息:
authorizationStatus() 在 iOS 14.0 中被弃用
要解决此问题,请使用以下内容:
private let locationManager = CLLocationManager()
if CLLocationManager.locationServicesEnabled() {
switch locationManager.authorizationStatus {
case .notDetermined, .restricted, .denied:
print("No access")
case .authorizedAlways, .authorizedWhenInUse:
print("Access")
@unknown default:
break
}
} else {
print("Location services are not enabled")
}
在objective-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 (截至 2018 年 7 月 24 日)
if CLLocationManager.locationServicesEnabled() {
}
这会告诉您用户是否已经为应用的位置权限请求选择了设置
对于swift3.0及以上版本,
如果经常检查位置服务的可用性,请创建一个 class,如下所示,
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)
}
}
它只是 Swift 4 中的一个 2 行函数:
import CoreLocation
static func isLocationPermissionGranted() -> Bool
{
guard CLLocationManager.locationServicesEnabled() else { return false }
return [.authorizedAlways, .authorizedWhenInUse].contains(CLLocationManager.authorizationStatus())
}
在Swift3.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
}
为您使用的定位服务请求许可:
yourSharedLocationManager.requestWhenInUseAuthorization()
如果当前状态未定,将显示警告提示用户允许访问。如果访问被拒绝,您的应用程序将在 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)
}
}
这是 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
}
}
}
}
Swift 5.2
首先,将用户 class 设置为 CLLocationManager 委托:
import SwiftUI
import CoreLocation
class User: NSObject, ObservableObject {
let manager = CLLocationManager()
override init() {
super.init()
manager.delegate = self
manager.requestWhenInUseAuthorization()
manager.requestLocation()
manager.startUpdatingLocation()
}
}
extension User: CLLocationManagerDelegate {
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
print("Location services authorization request")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("Location updated")
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Failed to find user's location: \(error.localizedDescription)")
}
}
然后在视图中:
if (user.manager.authorizationStatus == .denied) {
print("Location authorization denied, displaying sheet.")
}
我一直在研究 CoreLocation。最近,我遇到了一个在其他地方已经涵盖的问题,但是在 Objective C 和 iOS 8.
我觉得问这个问题有点傻,但是您如何在 iOS 9 上使用 swift 检查是否启用了定位服务?
在 iOS 7(也许是 8?)上,您可以使用 locationServicesEnabled()
,但在为 iOS 9.[=11= 编译时似乎不起作用]
那么我该如何完成呢?
谢谢!
当您调用 -startLocation 时,如果位置服务被用户拒绝,位置管理器委托将收到对 - locationManager:didFailWithError
的调用:带有 kCLErrorDenied
错误代码。这适用于 iOS.
将 CLLocationManagerDelegate
添加到您的 class 继承中,然后您可以进行此检查:
导入 CoreLocation 框架
import CoreLocation
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")
}
iOS 14.x
在 iOS 14 中,您将收到以下错误消息: authorizationStatus() 在 iOS 14.0 中被弃用要解决此问题,请使用以下内容:
private let locationManager = CLLocationManager()
if CLLocationManager.locationServicesEnabled() {
switch locationManager.authorizationStatus {
case .notDetermined, .restricted, .denied:
print("No access")
case .authorizedAlways, .authorizedWhenInUse:
print("Access")
@unknown default:
break
}
} else {
print("Location services are not enabled")
}
在objective-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 (截至 2018 年 7 月 24 日)
if CLLocationManager.locationServicesEnabled() {
}
这会告诉您用户是否已经为应用的位置权限请求选择了设置
对于swift3.0及以上版本, 如果经常检查位置服务的可用性,请创建一个 class,如下所示,
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)
}
}
它只是 Swift 4 中的一个 2 行函数:
import CoreLocation
static func isLocationPermissionGranted() -> Bool
{
guard CLLocationManager.locationServicesEnabled() else { return false }
return [.authorizedAlways, .authorizedWhenInUse].contains(CLLocationManager.authorizationStatus())
}
在Swift3.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
}
为您使用的定位服务请求许可:
yourSharedLocationManager.requestWhenInUseAuthorization()
如果当前状态未定,将显示警告提示用户允许访问。如果访问被拒绝,您的应用程序将在 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)
}
}
这是 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
}
}
}
}
Swift 5.2
首先,将用户 class 设置为 CLLocationManager 委托:
import SwiftUI
import CoreLocation
class User: NSObject, ObservableObject {
let manager = CLLocationManager()
override init() {
super.init()
manager.delegate = self
manager.requestWhenInUseAuthorization()
manager.requestLocation()
manager.startUpdatingLocation()
}
}
extension User: CLLocationManagerDelegate {
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
print("Location services authorization request")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("Location updated")
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Failed to find user's location: \(error.localizedDescription)")
}
}
然后在视图中:
if (user.manager.authorizationStatus == .denied) {
print("Location authorization denied, displaying sheet.")
}