在用户拒绝使用后,如何提示用户打开位置服务

GBe*_*gen 71 core-location ios

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

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

  1. 在设置>常规>重置>重置位置警告中重置位置警告.
  2. 启动地图应用.
  3. 点按左下角的"当前位置"按钮.
  4. 地图提示""地图"想要使用您当前的位置"| "不要允许"| "允许".
  5. 选择"不允许"选项.
  6. 再次点击左下角的"当前位置"按钮.
  7. 地图提示"打开位置服务以允许"地图"确定您的位置"| "设置"| "取消".

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

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

CLLocationManager类中有什么东西我错过了能够给我这个行为吗?

mob*_*com 42

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

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

在您的UIAlertView委托中:

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

  • 这比iOS 7及更早版本要好得多,但仍然不完美,因为URL会将您带到一个高于用户实际更改设置的屏幕. (4认同)

Lil*_*ard 32

更新:

从iOS 8开始,现在有UIApplicationOpenSettingsURLString一个代表URL 的常量,当打开时,会打开设置应用程序到您的应用程序的设置(然后用户可以重新启用位置服务).


原版的:

你无法做到这一点.您唯一真正的选择是显示一条警报,通知用户您的应用程序需要位置服务,并指示他们手动转到"设置"应用并将其打开.


Mar*_*kus 16

在iOS 8 中不推荐使用 AlertView .现在有一种更好的方法可以使用新的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];
Run Code Online (Sandbox Code Playgroud)


iOS*_*com 6

根据Apple的Docs上的LocationServicesEnabled方法.

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

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

所以你不能以任何方式启动位置服务更新以引起警报?

  • 它并没有真正起作用,可能与locationServicesEnabled和*authorized*之间的微妙区别有关.如果它们被禁用,它将提示启用,但如果它们被启用但被拒绝,则它将不执行任何操作.但这是非常令人困惑的文档. (15认同)

Mun*_*nib 6

这是Markus和bjc提供的代码的快速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)
Run Code Online (Sandbox Code Playgroud)


小智 5

在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)

   }
}
Run Code Online (Sandbox Code Playgroud)