ios 用户拒绝使用后如何提示用户打开定位服务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4891950/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:47:16  来源:igfitidea点击:

How can I prompt the user to turn on location services after user has denied their use

ioscore-location

提问by GBegen

I have an application with an explicit user interaction that makes use of the user's current location. If the user denies access to location services, I would still like subsequent uses to prompt the user to go to settings and re-enable location services for my app.

我有一个具有显式用户交互的应用程序,它利用了用户的当前位置。如果用户拒绝访问定位服务,我仍然希望后续使用能够提示用户转到设置并为我的应用重新启用定位服务。

The behavior I want is that of the built-in Maps app:

我想要的行为是内置地图应用程序的行为:

  1. Reset location warnings in Settings > General > Reset > Reset Location Warnings.
  2. Start Maps app.
  3. Tap Current Location button in lower left corner.
  4. Maps prompts with ""Maps" Would Like to Use Your Current Location" | "Don't Allow" | "Allow".
  5. Choose "Don't Allow" option.
  6. Tap Current Location button in lower left corner again.
  7. Maps prompts with "Turn On Location Services to Allow "Maps" to Determine Your Location" | "Settings" | "Cancel".
  1. 在“设置”>“通用”>“重置”>“重置位置警告”中重置位置警告。
  2. 启动地图应用程序。
  3. 点击左下角的当前位置按钮。
  4. 地图提示“”地图“想使用您当前的位置”| “不允许” | “允许”。
  5. 选择“不允许”选项。
  6. 再次点击左下角的当前位置按钮。
  7. 地图提示“打开定位服务以允许“地图”确定您的位置”| “设置” | “取消”。

In my own app, the same basic flow results in my CLLocationManagerDelegate -locationManager:didFailWithError: method being called with a kCLErrorDenied error at the final step and the user is not given the option to open the Settings app to correct it.

在我自己的应用程序中,相同的基本流程导致我的 CLLocationManagerDelegate -locationManager:didFailWithError: 方法在最后一步被调用,并带有 kCLErrorDenied 错误,并且用户没有选择打开设置应用程序来纠正它。

I could display my own alert in response to the error, but it would not have the ability to launch the Settings app like the alert that the OS can provide as used by the built-in Maps app.

我可以显示我自己的警报以响应错误,但它无法像内置地图应用程序使用的操作系统可以提供的警报那样启动设置应用程序。

Is there something in the CLLocationManager class I am missing that would be able to give me this behavior?

我缺少的 CLLocationManager 类中有什么东西可以给我这种行为吗?

采纳答案by mobileideafactory.com

With iOS8, you can finally link user to Settings app via openURL. For example, you can create a UIAlertView with a single button that takes user to the Settings app:

使用 iOS8,您最终可以通过 openURL 将用户链接到设置应用程序。例如,您可以创建一个带有单个按钮的 UIAlertView,将用户带到设置应用程序:

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:ICLocalizedString(@"LocationServicesPermissionTitle")
                                                    message:ICLocalizedString(@"LocationPermissionGeoFenceMessage")
                                                   delegate:self
                                          cancelButtonTitle:@"Settings"
                                          otherButtonTitles:nil];
    [alert show];

In your UIAlertView delegate:

在您的 UIAlertView 委托中:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    [alertView dismissWithClickedButtonIndex:buttonIndex animated:YES];
    [[UIApplication sharedApplication] openURL: [NSURL URLWithString: UIApplicationOpenSettingsURLString]];
}

回答by Lily Ballard

Update:

更新:

As of iOS 8, there is now the constant UIApplicationOpenSettingsURLStringwhich represents a URL that, when opened, opens the Settings app to your application's settings (where the user can then re-enable location services).

从 iOS 8 开始,现在有UIApplicationOpenSettingsURLString一个表示 URL的常量,当打开该 URL 时,会打开“设置”应用到您的应用程序的设置(用户可以在其中重新启用位置服务)。



Original:

原来的:

There is no way for you to do this. Your only real option is to display an alert informing the user that your application requires location services, and instructing them to manually go to the Settings app and turn it on.

你没有办法做到这一点。您唯一真正的选择是显示一个警报,通知用户您的应用程序需要定位服务,并指示他们手动转到“设置”应用程序并将其打开。

回答by Markus

AlertViews are deprecatedin iOS 8. There is now a better way to handle alerts using the new AlertController:

AlertViews在 iOS 8中弃用。 现在有一种更好的方法来使用新的 AlertController 处理警报:

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString( @"Enter your title here", @"" ) message:NSLocalizedString( @"Enter your message here.", @"" ) preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString( @"Cancel", @"" ) style:UIAlertActionStyleCancel handler:nil];
UIAlertAction *settingsAction = [UIAlertAction actionWithTitle:NSLocalizedString( @"Settings", @"" ) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
   [[UIApplication sharedApplication] openURL:[NSURL URLWithString:
                                                    UIApplicationOpenSettingsURLString]];
}];

[alertController addAction:cancelAction];
[alertController addAction:settingsAction];

[self presentViewController:alertController animated:YES completion:nil];

回答by FlowUI. SimpleUITesting.com

According to Apple's Docson the locationServicesEnabledmethod.

根据Apple 的关于locationServicesEnabled方法的文档

The user can enable or disable location services from the Settings application by toggling the Location Services switch in General.

You should check the return value of this method before starting location updates to determine whether the user has location services enabled for the current device. If this method returns NO and you start location updates anyway, the Core Location framework prompts the user to confirm whether location services should be reenabled.

用户可以通过在常规中切换定位服务开关,从设置应用程序启用或禁用定位服务。

您应该在开始位置更新之前检查此方法的返回值,以确定用户是否为当前设备启用了位置服务。如果此方法返回 NO 并且您仍然开始位置更新,则核心位置框架会提示用户确认是否应重新启用位置服务。

So cant you just start location services updates any way to cause the alert to be prompted?

因此,您不能以任何方式启动位置服务更新以导致提示警报吗?

回答by Munib

Here is the swift 3 implementation of the code provided by Markus and bjc.

这是 Markus 和 bjc 提供的代码的 swift 3 实现。

let alertController = UIAlertController(title: NSLocalizedString("Enter your title here", comment: ""), message: NSLocalizedString("Enter your message here.", comment: ""), preferredStyle: .alert)

let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: nil)
let settingsAction = UIAlertAction(title: NSLocalizedString("Settings", comment: ""), style: .default) { (UIAlertAction) in
                UIApplication.shared.openURL(NSURL(string: UIApplicationOpenSettingsURLString)! as URL)
            }

alertController.addAction(cancelAction)
alertController.addAction(settingsAction)
            self.present(alertController, animated: true, completion: nil)

回答by omi23

In Swift 4, there is an update in its syntax.

在 Swift 4 中,其语法进行了更新。

Swift 4

斯威夫特 4

extension UIAlertController {

    func createSettingsAlertController(title: String, message: String) {

      let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)

      let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: nil)
      let settingsAction = UIAlertAction(title: NSLocalizedString("Settings", comment: ""), style: .default) { (UIAlertAction) in
        UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)! as URL, options: [:], completionHandler: nil)
      }

      alertController.addAction(cancelAction)
      alertController.addAction(settingsAction)
      self.present(alertController, animated: true, completion: nil)

   }
}

回答by Oliver

I guess you will have an answer to your question when Apple will think about a new SDK. At current time and as far as I know, it's not possible :

我想当 Apple 考虑新的 SDK 时,您的问题就会有答案。目前,据我所知,这是不可能的:

No URL-Handler available
No usable method to call

没有可用的 URL-Handler
没有可用的调用方法

But... As Maps does it, this CAN be done, but probably using a private API. If you're not afraid with this kind of coding, you should search there in my opinion.

但是...正如地图所做的那样,这可以完成,但可能使用私有 API。如果你不害怕这种编码,我认为你应该在那里搜索。

回答by Pramod More

Swift,

斯威夫特

Once you disable location services for an app, location manager delegate methods will start showing error. So, on receiving error we can check if location services are enabled/disabled. And according to the result, we can ask the user to go to settings and turn on location services.

一旦您为应用程序禁用位置服务,位置管理器委托方法将开始显示错误。因此,在收到错误时,我们可以检查位置服务是否已启用/禁用。根据结果​​,我们可以要求用户进入设置并开启定位服务。

In your location manager delegate method for error, add location permission check

在您的位置管理器委托方法中,添加位置权限检查

func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
            //check  location permissions
            self.checkLocationPermission()
        }
}

Code for location permission checking

代码位置权限检查

//check location services enabled or not

    func checkLocationPermission() {
        if CLLocationManager.locationServicesEnabled() {
            switch(CLLocationManager.authorizationStatus()) {
            case .notDetermined, .restricted, .denied:
                //open setting app when location services are disabled
            openSettingApp(message:NSLocalizedString("please.enable.location.services.to.continue.using.the.app", comment: ""))
            case .authorizedAlways, .authorizedWhenInUse:
                print("Access")
            }
        } else {
            print("Location services are not enabled")
            openSettingApp(message:NSLocalizedString("please.enable.location.services.to.continue.using.the.app", comment: ""))
        }
    }

Code to open settings app,

打开设置应用程序的代码,

//open location settings for app
func openSettingApp(message: String) {
    let alertController = UIAlertController (title: APP_NAME_TITLE, message:message , preferredStyle: .alert)

    let settingsAction = UIAlertAction(title: NSLocalizedString("settings", comment: ""), style: .default) { (_) -> Void in
        guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
            return
        }

        if UIApplication.shared.canOpenURL(settingsUrl) {
            UIApplication.shared.open(settingsUrl, options: [:], completionHandler: nil)
        }
    }
    alertController.addAction(settingsAction)
    let cancelAction = UIAlertAction(title: NSLocalizedString("cancel", comment: ""), style: .default, handler: nil)
    alertController.addAction(cancelAction)

    present(alertController, animated: true, completion: nil)
}

回答by Chris

latest swift version based on answers above.

基于上述答案的最新 swift 版本。

func showSettingsAlert(_ from:UIViewController, title:String?, message:String?) {

        let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)

        let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: nil)

        let settingsAction = UIAlertAction(title: NSLocalizedString("Settings", comment: ""), style: .default) { (UIAlertAction) in

            guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
                return
            }

            if UIApplication.shared.canOpenURL(settingsUrl) {
                UIApplication.shared.open(settingsUrl, options: [:], completionHandler: nil)
            }
        }

        alertController.addAction(cancelAction)
        alertController.addAction(settingsAction)
        from.present(alertController, animated: true, completion: nil)
    }

回答by bjc

Here's a Swift version of the code in the answer by Markus. This code creates an alert that gives the user the option to open Settings.

这是 Markus 答案中代码的 Swift 版本。此代码创建为用户提供选项来打开设置警报。

let alertController = UIAlertController(title: NSLocalizedString("Enter your title here", comment: ""), message: NSLocalizedString("Enter your message here.", comment: ""), preferredStyle: .Alert)

let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .Cancel, handler: nil)
let settingsAction = UIAlertAction(title: NSLocalizedString("Settings", comment: ""), style: .Default) { (UIAlertAction) in
    UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)
}

alertController.addAction(cancelAction)
alertController.addAction(settingsAction)
self.presentViewController(alertController, animated: true, completion: nil)