【问题标题】:iOS: make "Location" appear in the app settings without requesting for location authorization (Tile app example)iOS:使“位置”出现在应用设置中而不请求位置授权(平铺应用示例)
【发布时间】:2020-04-22 00:57:58
【问题描述】:

长话短说:

我想让“位置”出现在应用设置中,而不像 Tile 应用那样请求位置授权。

重现步骤:

  1. 安装磁贴应用程序。
    • 应用设置中没有“位置”。
  2. 打开应用,接受蓝牙访问请求(有关系吗?)。
    • 应用设置中仍然没有“位置”,但出现了蓝牙。
  3. 使用应用程序大约 20 秒(不能更短)。
    • “位置”出现在应用设置中 - 如何?

这在下面的视频中展示:

https://media.giphy.com/media/h5dPQPbBHzEhdLTrKz/giphy.gif

我怎样才能做到这一点?


背景 - 为什么

自 iOS 13 起,无法直接向用户询问Always 位置授权。当开发者请求Always授权时,用户只能选择While in Use选项,应用获得Provisional Always授权。直到再次提示用户(iOS 决定何时),用户将在应用设置中看到While in Use 授权。

这意味着:

  • Always --> 应用设置中的CLAuthorizationStatus.authorizedAlways 和Always。

  • Provisional Always --> 应用设置中也有CLAuthorizationStatus.authorizedAlways 但While in Use。

这在this Stack Overflow answer中有很好的描述。

The problem is that the application cannot read the location in the background without Always authorization(可以,但只能持续 5-10 秒),这极大地限制了某些应用程序(例如 iBeacon 跟踪器)的主要功能。

一个众所周知的做法是检查应用程序是否具有Always 授权,如果没有,请提供说明为什么这很重要以及用户如何更改它的信息(在设置中手动)。

但是我们无法区分是Always还是Provisional Always授权状态(at least directly),所以逻辑:

if (CLLocationManager.authorizationStatus() != .authorizedAlways) {
    // Prompt the user to change Location access to Always manually in settings
}

不适用于Provisional Always 授权状态。

解决办法可以是要求用户在请求位置授权之前在设置中手动选择Always,以防止出现Provisional Always状态。我认为不先打电话给requestAlwaysAuthorization() 是不可能的,但是 Tile 以某种方式做到了,如上一个视频中所述。

更新:

我已经有了:

  • NSLocationAlwaysAndWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription
  • NSLocationWhenInUseUsageDescription

Info.plist 文件中设置的私钥。

【问题讨论】:

    标签: ios core-location cllocationmanager ibeacon ios13


    【解决方案1】:

    要在应用设置中显示“位置”而不事先征求许可(Always 需要两步选择加入),您需要致电locationManager.requestLocation()。

    func scheduleLocationUpdates() {
        if CLLocationManager.locationServicesEnabled() && CLLocationManager.authorizationStatus() == .authorizedAlways {
            locationManager.startUpdatingLocation()
            // hide full screen instruction (if shown)
        } else {
            if (UIDevice.current.systemVersion as NSString).floatValue >= 13.0 {
                locationManager.requestLocation() // reveal "Location" in app settings (works on iOS 13 only)
                // show full screen instruction how to provide "Always authorization"
            } else {
                if CLLocationManager.authorizationStatus() == .notDetermined {
                    locationManager.requestAlwaysAuthorization()
                } else {
                    // show full screen instruction how to provide "Always authorization"
                }
            }
        }
    }
    

    函数scheduleLocationUpdates() 应该在viewWillAppear 和UIApplication.willEnterForegroundNotification 事件之后调用(例如,当用户从设置返回时)。

    在 iOS 12 上,“位置”不会出现在应用设置中,无需先请求权限。但您可以直接请求Always 权限(无需两步),所以这不是必要的。

    【讨论】:

      【解决方案2】:

      您是否尝试过简单地将NSLocationAlwaysAndWhenInUseUsageDescription 键放入您的plist,然后实例化一个CLLocationServices 实例并使用它来尝试开始位置更新?我怀疑这会导致该条目出现在设置中,即使在授予权限之前位置更新不会起作用。

      【讨论】:

      • 是的,我有钥匙,但是在没有请求许可的情况下开始更新位置很有帮助。谢谢!虽然我有点担心它可能会在一些 iOS 更新后停止工作,但这听起来不像是一项功能。
      • Apple 总是有可能在这里做出未来的改变(Apple 经常让我们感到惊讶!),但我认为使用这种技术是相当安全的,因为我相信它与 Apple 希望他们的方式一致权限系统才能工作——只有当应用程序尝试使用位置时,权限设置才会显示。只是我的两分钱。
      • 这仅适用于 iOS13。 这就是使用无证行为的风险...
      猜你喜欢
      • 2015-02-01
      • 2014-08-21
      • 1970-01-01
      • 2019-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-17
      • 2016-06-14
      相关资源
      最近更新 更多