87

我刚刚使用 iOS 11 SDK 重建了我的应用程序,试图删除blue banner现在总是出现的应用程序。我想 - “太棒了,这有效”,却发现定位服务现在根本不起作用。

该应用程序曾经与 iOS 10 一起使用 - 有人听说过吗?

4

8 回答 8

157

苹果似乎又增加了一项隐私功能。用户现在可以覆盖我们requestAlwaysAuthorization并将其降级为requestWhenInUseAuthorization- 这意味着作为开发人员,我们现在必须在Info.plist

我发现他们添加了一个新密钥NSLocationAlwaysAndWhenInUseUsageDescription

/*
*      Either the NSLocationAlwaysAndWhenInUseUsageDescription key or both the
*      NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription
*      keys must be specified in your Info.plist; otherwise, this method will do
*      nothing, as your app will be assumed not to support Always authorization.
*/

但是,在使用这个新密钥后 - 位置服务仍然无法工作,在进一步搜索后,我发现这个 gem 与所有额外的调试信息混合在一起:

此应用程序试图在没有使用说明的情况下访问隐私敏感数据。应用的 Info.plist 必须同时包含 NSLocationAlwaysAndWhenInUseUsageDescription 和 NSLocationWhenInUseUsageDescription 键,其中包含向用户解释应用如何使用这些数据的字符串值

这与我在更新CLLocationManager.h文件中找到的评论直接矛盾。所以我创建了一个雷达。

好消息,如果你听从调试控制台 IE 的建议。添加新密钥NSLocationAlwaysAndWhenInUseUsageDescription和旧密钥之一NSLocationWhenInUseUsageDescription,位置服务将再次开始工作。

于 2017-06-07T23:39:23.430 回答
46

只需添加修复此问题的步骤:

2种方法来做到这一点:

A)简单的方法:选择您的 Info.plist 文件,添加属性,注意它们以 PRIVCY 而不是 LOCATION 开头...因此,这些变量的确切名称以“Privacy - Location ...”等开头,添加每个在这里,并描述用户如何在警告中看到这一点。

B)硬/有趣/程序化的方式(我更喜欢这种方式):

右键单击您的应用程序的 Info.plist,然后选择“查看源代码”,您应该在 XML 中看到它,

按照其他......格式,并添加这些属性如下:

<key>NSLocationAlwaysUsageDescription</key>
<string>Program requires GPS to track cars and job orders</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Program requires GPS to track cars and job orders</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Program requires GPS to track cars and job orders</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app uses your Microphone to allow Voice over IP communication with the Program Admin system</string>

保存,然后右键单击 info.plist 文件,然后选择属性列表,这应该将文件查看回默认视图。

编辑:

另一位会员要代码,这里是:

1) 在您的 .H 文件中,添加:

@property (strong, nonatomic) CLLocationManager *LocationManager;

2) 在您的 .M 文件中添加 ViewDidAppear() 函数:

_LocationManager = [[CLLocationManager alloc] init];
[_LocationManager setDelegate:self];
_LocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
_LocationManager.pausesLocationUpdatesAutomatically = NO;
[_LocationManager requestAlwaysAuthorization];

_LocationManager.headingFilter = 5;
_LocationManager.distanceFilter = 0;

[_LocationManager startUpdatingLocation];
[_LocationManager startUpdatingHeading];

这对我来说很好,希望代码也对你有用。

问候

海德

于 2017-09-22T22:43:04.727 回答
23

在 iOS11 下工作我发现,Info.plist 至少需要 Info.plist 中的 NSLocationAlwaysAndWhenInUseUsageDescription:

在此处输入图像描述

奇怪的是,当您的应用程序是多语言的时,您的字符串的本地化版本需要本文中提到的所有三个键requestAlwaysAuthorization(),并且locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) 会静默失败。

以德语翻译为例:

在此处输入图像描述

希望这可以节省您偶然发现的时间。

于 2017-10-19T05:54:10.657 回答
17

在 Swift 4.0.3 中工作

   <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
   <string>Description</string>

   <key>NSLocationAlwaysUsageDescription</key>
   <string>Will you allow this app to always know your location?</string>

   <key>NSLocationWhenInUseUsageDescription</key>
   <string>Do you allow this app to know your current location?</string>  
于 2018-01-29T09:20:07.767 回答
16

按着这些次序:

我在需要“始终授权”的应用程序中遇到了同样的问题,并通过以下步骤解决了它:

1. 添加 NSLocationWhenInUseUsageDescription密钥Info.plist

2. 添加 NSLocationAlwaysAndWhenInUseUsageDescriptionInfo.plist

3. 添加 NSLocationAlwaysUsageDescriptionInfo.plist(支持<iOS 11)

4. 打电话 requestWhenInUseAuthorization() 之前 requestAlwaysAuthorization(

您不能在 requestWhenInUseAuthorization() 之前执行 requestAlwaysAuthorization()。您必须升级到该权限级别。一旦我进行了这些更改,位置更新就会再次开始正常工作。

更多详情可在这找到:

https://developer.apple.com/documentation/corelocation/choosing_the_authorization_level_for_location_services/requesting_always_authorization

于 2017-12-01T05:42:30.007 回答
6

比抱歉更安全.. 在 iOS 11 中:添加以下内容,您就很好了。

<key>NSLocationWhenInUseUsageDescription</key>
<string>Description</string>

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Description</string>

<key>NSLocationAlwaysUsageDescription</key>
<string>Description</string>
于 2017-12-06T06:25:54.117 回答
5

使用Swift 5在iOS 12.2上测试

步骤 1. 您必须在 plist 文件中添加以下隐私权限

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Application requires user’s location for better user experience.</string>

<key>NSLocationAlwaysUsageDescription</key>
<string>Application requires user’s location for better user experience.</string>

<key>NSLocationWhenInUseUsageDescription</key>
<string>Application requires user’s location for better user experience.</string>

第 2 步。确保您有以下 swift 代码来获取当前位置

import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

    // MARK: Variables declearations
    @IBOutlet weak var mapView: MKMapView!
    var locationManager: CLLocationManager!

    // MARK: View Controller life cycle methods
    override func viewDidLoad() {
        super.viewDidLoad()
        //TODO: Make user you must add following three privacy permissions in plist
        //NSLocationWhenInUseUsageDescription
        //NSLocationAlwaysAndWhenInUseUsageDescription
        //NSLocationAlwaysUsageDescription

        getCurrentLocation()
    }

    func getCurrentLocation()
    {
        if (CLLocationManager.locationServicesEnabled())
        {
            locationManager = CLLocationManager()
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
            locationManager.requestAlwaysAuthorization()
            locationManager.startUpdatingLocation()
        }
    }

    // MARK: Location Manager Delegate methods
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
    {
        let locationsObj = locations.last! as CLLocation
        print("Current location lat-long is = \(locationsObj.coordinate.latitude) \(locationsObj.coordinate.longitude)")
        showOnMap(location: locationsObj)
    }
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("Get Location failed")
    }

    func showOnMap(location: CLLocation )
    {
        let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
        mapView.setRegion(region, animated: true)
    }
}
于 2019-05-15T05:46:17.080 回答
3

斯威夫特:3 我也遇到过同样的问题。我完全搞砸了寻找解决方案。这是我解决问题的方法。

第 1 步:项目文件 > 功能 > 背景模式 > 选择位置更新

第 2 步: 将 NSLocationWhenInUseUsageDescription 、 NSLocationAlwaysAndWhenInUseUsageDescription 键添加到Info.plist

第 3 步:

manager.pausesLocationUpdatesAutomatically = false
manager.allowsBackgroundLocationUpdates = true
于 2018-06-07T05:56:00.570 回答