定位服务在 iOS 11 中不工作

Location Services not working in iOS 11

我刚刚用 iOS 11 SDK 重建了我的应用程序,试图删除现在总是出现的 blue banner。我以为 - "Brilliant, that worked",却发现定位服务现在根本不起作用。

该应用程序曾用于 iOS 10 - 有人听说过吗?

Apple 似乎又增加了一项隐私功能。用户现在可以覆盖我们的 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 与所有额外的调试信息混合在一起:

This app has attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain both NSLocationAlwaysAndWhenInUseUsageDescription and NSLocationWhenInUseUsageDescription keys with string values explaining to the user how the app uses this data

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

好消息,如果您遵循调试控制台 IE 的建议。添加新密钥 NSLocationAlwaysAndWhenInUseUsageDescription 和其中一个旧密钥 NSLocationWhenInUseUsageDescription,位置服务将再次开始工作。

只是添加解决此问题的步骤:

2 种方法:

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

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

右键单击您的应用程序 Info.plist,然后 select "View source code",您应该会在 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文件,然后select属性列表,这样应该查看文件回到默认视图。

编辑:

又有会员要代码,这里是:

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];

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

此致

黑德

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

中的 NSLocationAlwaysAndWhenInUseUsageDescription

当你的应用程序是多语言时,你的字符串的本地化版本需要所有三个键 post否则 requestAlwaysAuthorization()locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) 将无声地失败。

以德语翻译为例的截图:

希望这能为您在偶然发现时节省时间。

按照以下步骤操作:

我 运行 遇到了与需要 "Always Authorization" 的应用程序相同的问题,并按照以下步骤解决了该问题:

1. 添加 NSLocationWhenInUseUsageDescription键到Info.plist

2. 添加 NSLocationAlwaysAndWhenInUseUsageDescriptionInfo.plist

3.添加NSLocationAlwaysUsageDescriptionInfo.plist(支持

4. 调用 requestWhenInUseAuthorization() BEFORE requestAlwaysAuthorization()

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

可以在此处找到更多详细信息:

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

安全总比遗憾好.. 在 iOS 11 中:添加以下内容即可。

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

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

<key>NSLocationAlwaysUsageDescription</key>
<string>Description</string>

正在使用 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>  

Swift : 3 我遇到了同样的问题。我完全搞砸了寻找解决方案。这是我解决问题的方法。

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

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

第 3 步:

manager.pausesLocationUpdatesAutomatically = false
manager.allowsBackgroundLocationUpdates = true

iOS 12.2 上测试 Swift 5

第 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)
    }
}