简体   繁体   English

位置服务在iOS 11中不起作用

[英]Location Services not working in iOS 11

I just rebuilt my app with the iOS 11 SDK in an attempt to remove the blue banner that is now always appearing. 我刚用iOS 11 SDK重建了我的应用程序,试图删除现在总是出现的blue banner I thought - "Brilliant, that worked", only to discover that location services are now not working at all. 我想 - “太棒了,有用”,却发现定位服务现在根本不起作用。

The application used to work with iOS 10 - Has anybody heard anything? 用于iOS 10的应用程序 - 有没有人听到过什么?

It would appear that apple have added yet another privacy feature. 苹果似乎又添加了另一项隐私功能。 The user is now able to override our requestAlwaysAuthorization and downgrade it to requestWhenInUseAuthorization - Which means as a developer we now have to supply both descriptions in the Info.plist 用户现在可以覆盖我们的requestAlwaysAuthorization并将其降级为requestWhenInUseAuthorization - 这意味着作为开发人员,我们现在必须在Info.plist提供这两个描述

I found that they have added a new key NSLocationAlwaysAndWhenInUseUsageDescription 我发现他们已经添加了一个新密钥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.
*/

However, upon using this new key - the location service still didn't work, upon further searching I found this gem mixed in with all the extra debugging information: 然而,在使用这个新密钥时 - 位置服务仍然无法工作,在进一步搜索时,我发现这个宝石混入了所有额外的调试信息:

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 应用程序的Info.plist必须包含NSLocationAlwaysAndWhenInUseUsageDescription和NSLocationWhenInUseUsageDescription键,并带有字符串值,向用户解释应用程序如何使用此数据

Which directly contradicts the the comment that I found in the updated CLLocationManager.h file. 这与我在更新的CLLocationManager.h文件中找到的注释直接相矛盾。 So I've created a radar. 所以我创造了一个雷达。

Good news, if you follow the advice of the debugging console, IE. 好消息,如果你按照调试控制台的建议,IE。 add both the new key NSLocationAlwaysAndWhenInUseUsageDescription and one of the old keys NSLocationWhenInUseUsageDescription , locations services will start to work again. 添加新密钥NSLocationAlwaysAndWhenInUseUsageDescription和其中一个旧密钥NSLocationWhenInUseUsageDescription ,位置服务将再次开始工作。

Just to add the steps on fixing this: 只是添加修复此步骤的步骤:

2 ways to do it: 2种方法:

A) The easy way: Select your Info.plist file, add the properties, note that they start with PRIVCY instead of LOCATION... therefore, the exact names of these variables starts with "Privacy - Location ... " etc, add each here, and describe how the user would be seeing this on the warning. A)简单的方法:选择你的Info.plist文件,添加属性,注意它们以PRIVCY而不是LOCATION开头...因此,这些变量的确切名称以“Privacy - Location ...”等开头,添加每个都在这里,并描述用户将如何在警告上看到这一点。

B) The hard / interesting / programatic way (I like this way more): B)硬/有趣/程序化的方式(我更喜欢这种方式):

Right click on your Info.plist for your app, and then select "View source code", you should see it all in XML, 右键单击您的应用程序的Info.plist,然后选择“查看源代码”,您应该在XML中看到它,

Follow the other ...... format, and add these properties as follows: 遵循其他......格式,并添加以下属性:

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

Save, and then right-click on the info.plist file, and then select Property list, this should view the file back into the default view. 单击保存,然后右键单击info.plist文件,然后选择属性列表,这应该将文件返回到默认视图。

EDIT: 编辑:

Another member asked for code, here it is: 另一位成员要求代码,这里是:

1) On your .H file, add: 1)在.H文件中,添加:

@property (strong, nonatomic) CLLocationManager *LocationManager;

2) On your .M file add under ViewDidAppear() function: 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];

This what works fine for me, hopefully the code would work for you too. 这对我来说很好,希望代码也适合你。

Regards 问候

Heider 海德

working under iOS11 i discovered, that Info.plist needs al least NSLocationAlwaysAndWhenInUseUsageDescription in Info.plist: 在iOS11下我发现,Info.plist在Info.plist中至少需要NSLocationAlwaysAndWhenInUseUsageDescription:

在此输入图像描述

Strange enough when your app is multilingual the localized versions of your strings need all three keys mentioned in this post else requestAlwaysAuthorization() and locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) will fail silently. 当您的应用程序是多语言时,奇怪的是,您的字符串的本地化版本需要此帖子中提到的所有三个键 ,否则requestAlwaysAuthorization()locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus)将无声地失败。

Shot showing german translation as example: 拍摄显示德语翻译为例:

在此输入图像描述

Hope this saves you time when stumbling upon. 希望这可以节省你绊倒的时间。

Working in Swift 4.0.3 在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>  

Follow these steps: 跟着这些步骤:

I ran into the same issue with an app that needed "Always Authorization", and resolved it by following these steps: 我遇到了一个需要“始终授权”的应用程序遇到了同样的问题,并通过以下步骤解决了这个问题:

1. Add NSLocationWhenInUseUsageDescription key to Info.plist 1. NSLocationWhenInUseUsageDescription添加Info.plist

2. Add NSLocationAlwaysAndWhenInUseUsageDescription to Info.plist 2. NSLocationAlwaysAndWhenInUseUsageDescription 添加Info.plist

3. Add NSLocationAlwaysUsageDescription to Info.plist (to support < iOS 11) 3. NSLocationAlwaysUsageDescription 添加Info.plist (以支持<iOS 11)

4. Call requestWhenInUseAuthorization() BEFORE requestAlwaysAuthorization( ) 4. requestAlwaysAuthorization(之前 调用 requestWhenInUseAuthorization() requestAlwaysAuthorization(

You cannot execute requestAlwaysAuthorization() before requestWhenInUseAuthorization(). 您无法在requestWhenInUseAuthorization()之前执行requestAlwaysAuthorization()。 You must escalate to that permission level. 您必须升级到该权限级别。 Once I made these changes, location updates started working properly again. 完成这些更改后,位置更新再次开始正常工作。

More details can be found here: 更多详情可在这找到:

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

Better safe than sorry .. In iOS 11 : Add the below and you are good. 比抱歉更安全..在iOS 11中:添加以下内容,你很好。

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

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

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

Swift : 3 i have faced the same issue. 斯威夫特:3我遇到了同样的问题。 i was totally screwed up finding the solution. 我完全搞砸了找到解决方案。 here is how i fixed the issue. 这是我如何解决这个问题。

step-1 : Project file > Capabilities > background modes > select Location Update 步骤1:项目文件>功能>后台模式>选择位置更新

step-2 : Add NSLocationWhenInUseUsageDescription , NSLocationAlwaysAndWhenInUseUsageDescription keys to Info.plist 步骤2:将NSLocationWhenInUseUsageDescription,NSLocationAlwaysAndWhenInUseUsageDescription键添加到Info.plist

step-3 : 第3步:

manager.pausesLocationUpdatesAutomatically = false
manager.allowsBackgroundLocationUpdates = true

Tested on iOS 12.2 with Swift 5 使用Swift 5iOS 12.2上测试

Step 1. you must add following privacy permissions in plist file 步骤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>

Step 2. make sure you have following swift code to get current locations 第2步。确保您有以下快速代码来获取当前位置

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM