长话短说:

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

ios - iOS:在应用程序设置中显示“位置”,而无需请求位置授权(瓷砖应用程序示例)-LMLPHP

重现步骤:

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

  • 这在下面的视频中介绍:

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

    我该如何实现?

    背景-为什么

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

    意思是:
  • Always->应用程序设置中的CLAuthorizationStatus.authorizedAlwaysAlways
  • Provisional Always->在应用程序设置中也是CLAuthorizationStatus.authorizedAlwaysWhile 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授权,如果没有,请提供信息,说明为什么这很重要以及用户如何更改(手动设置)。

    但是我们无法区分我们是否具有AlwaysProvisional 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文件中设置的隐私密钥。

    最佳答案

    要在应用设置中显示“位置”而无需先征得许可(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许可(无需两个步骤),因此这不是必需的。

    10-04 19:33