CLLocationManager 授权问题 iOS 8

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24669985/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:18:51  来源:igfitidea点击:

CLLocationManager authorization issue iOS 8

iosswiftcore-locationcllocationmanager

提问by brisi123

I am working on a piece of Swift code for iOS 8. I am trying to do something which involves location, and so i have implemented the following in my swift view controller file:

我正在为 iOS 8 编写一段 Swift 代码。我正在尝试做一些涉及位置的事情,所以我在我的 swift 视图控制器文件中实现了以下内容:

let locationManger:CLLocationManager = CLLocationManager()

let locationManger:CLLocationManager = CLLocationManager()

var speedReceived:Double = 0

override func viewDidLoad() {
    super.viewDidLoad()
    locationManger.delegate = self
    locationManger.desiredAccuracy = kCLLocationAccuracyBest
    let authstate = CLLocationManager.authorizationStatus()
    if(authstate == CLAuthorizationStatus.NotDetermined){
       println("Not Authorised")  
      locationManger.requestWhenInUseAuthorization()
    }
    // Do any additional setup after loading the view, typically from a nib.
}

func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!){
    var location:CLLocation = locations[locations.count - 1] as CLLocation
    if(location.horizontalAccuracy > 0){
        self.speedReceived = location.speed
        println(self.speedReceived)
    }
}

func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
   println("Couldn't get your location")
}

However, I can't seem to get this code to work. It doesn't save my preference for location use. it doesn't even prompt me to give permit to access location. I have tried updating my info.plist. But it's not working. Btw, if i select always in the privacy settings within the simulator, it works if i switch back to the app immediately. can anyone help? I am sure that that's the problem because i get Not Authorised on my console.

但是,我似乎无法让这段代码工作。它不会保存我对位置使用的偏好。它甚至没有提示我允许访问位置。我尝试更新我的 info.plist。但它不起作用。顺便说一句,如果我在模拟器中的隐私设置中始终选择,如果我立即切换回应用程序,它会起作用。有人可以帮忙吗?我确信这就是问题所在,因为我在我的控制台上没有获得授权。

Any help?

有什么帮助吗?

回答by Alex Peda

It's an iOS 8 related issue. You have to put NSLocationAlwaysUsageDescriptionor NSLocationWhenInUseUsageDescriptionkeys in your .plistfile (value may be an additional message that will be presented in location alert). These keys are required in iOS 8.

这是一个与 iOS 8 相关的问题。您必须在您的文件中输入NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription.plist(值可能是将在位置警报中显示的附加消息)。这些密钥在 iOS 8 中是必需的。

How it's said in Apple guidelines:

苹果指南中是这样说的:

This key is required when you use the requestAlwaysAuthorization method of the CLLocationManager class to request authorization for location services. If this key is not present and you call the requestAlwaysAuthorization method, the system ignores your request and prevents your app from using location services.

当您使用CLLocationManager 类的requestAlwaysAuthorization 方法请求位置服务授权时,需要此密钥。如果此键不存在并且您调用 requestAlwaysAuthorization 方法,系统将忽略您的请求并阻止您的应用使用位置服务。

回答by Cole Richards

I had struggled with a similar issue, which persisted even after adding the NSLocationAlwaysUsageDescription/NSLocationWhenInUseUsageDescription keys to the plist.

我一直在努力解决类似的问题,即使在将 NSLocationAlwaysUsageDescription/NSLocationWhenInUseUsageDescription 键添加到 plist 后,该问题仍然存在。

Eventually, I added the "Privacy - Location Usage Description" key to the plist (in addition to the new keys) and voila, it worked! After it worked once I was able to remove the "Privacy - Location Usage Description" key from the plist and continue to successfully request authorization.

最终,我在 plist 中添加了“隐私 - 位置使用说明”键(除了新键),瞧,它起作用了!在它工作后,我能够从 plist 中删除“隐私 - 位置使用说明”键并继续成功请求授权。

回答by hrchen

iOS 8 has changed location authorization strategy. Solution with backward compatibility:

iOS 8 更改了位置授权策略。具有向后兼容性的解决方案:

SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
    [self.locationManager respondsToSelector:requestSelector]) {
    [self.locationManager performSelector:requestSelector withObject:NULL];
} else {
    [self.locationManager startUpdatingLocation];
}

Reminder: setup NSLocationWhenInUseUsageDescription key in your Info.plist

提醒:在 Info.plist 中设置 NSLocationWhenInUseUsageDescription 键

回答by Chris Marshall

I had the exact same issue.

我有完全相同的问题。

For the record, this is not the official answer. The first answer is the correct one. I just wanted to add a link to a FOSS (Objective-C) project that illustrates the fix.

根据记录,这不是官方答案。第一个答案是正确的。我只是想添加一个链接到一个 FOSS (Objective-C) 项目来说明这个修复。

As noted, I had to add the key. My app does not need to run in the background, so I added the NSLocationWhenInUseUsageDescriptionkey to my info.plist.

如前所述,我必须添加密钥。我的应用程序不需要在后台运行,所以我在info.plist 中添加了NSLocationWhenInUseUsageDescription键。

If you add a string as the value for this key (optional -the existence of the key is enough to set the bar), then that string will appear in the authorization popup.

如果您添加一个字符串作为此密钥的值(可选 - 密钥的存在足以设置栏),那么该字符串将出现在授权弹出窗口中。

I then added the following code before all my [CLLocationManager startUpdating] calls:

然后我在所有 [CLLocationManager startUpdating] 调用之前添加了以下代码:

if ( [locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)] )
{
    [locationManager requestWhenInUseAuthorization];
}

The respondsToSelector is important, as the call is only available in iOS 8.

RespondsToSelector 很重要,因为该调用仅在 iOS 8 中可用。

The first time this is called, the alert is shown. After that, it falls through.

第一次调用时,会显示警报。在那之后,它就失败了。

Note that I call requestWhenInUseAuthorization

请注意,我调用requestWhenInUseAuthorization

It has to match the value I put in the plist. I guess you could put both, but I dunno. I didn't need to.

它必须与我放入 plist 的值相匹配。我想你可以放两个,但我不知道。我不需要。

The project is here. Most of the work (not much) is in the BMLTAppDelegate.mfile.

该项目在这里。大多数工作(不多)都在BMLTAppDelegate.m文件中。

This is a nasty surprise. Lots of folks have no idea that their apps will stop working in iOS 8. They'll do the same thing I initially did: Give it a quick run in the simulator, note the hang, and chalk it up to a beta bug.

这是一个令人讨厌的惊喜。很多人不知道他们的应用程序将在 iOS 8 中停止工作。他们会做我最初做的事情:在模拟器中快速运行,注意挂起,并将其归结为测试版错误。

Now, I have a different problem: All my apps are fixed, but Xcode crashes when I try to upload the apps to the App Store. I have a RADAR open on it.

现在,我遇到了一个不同的问题:我的所有应用程序都已修复,但是当我尝试将应用程序上传到 App Store 时,Xcode 崩溃了。我在上面打开了一个雷达。

Xcode 6 is kinda creaky. I expect a patch to come out pretty quickly.

Xcode 6 有点吱吱作响。我希望补丁很快出来。

回答by Vincent

Since I do not like to edit the plist directly, I always grant autorisation by using the UI.

由于我不喜欢直接编辑 plist,因此我总是使用 UI 授予授权。

enter image description here

在此处输入图片说明

The Dutch texts "Toegang is nodig" and "Toegang is noodzakelijk" are displayed in the PopUp in which the used grants access. You can change these to any text you like.

荷兰语文本“Toegang is nodig”和“Toegang is noodzakelijk”显示在已使用的授予访问权限的弹出窗口中。您可以将这些更改为您喜欢的任何文本。

Simply add to plist source,

只需添加到 plist 源,

<key>NSLocationAlwaysUsageDescription</key>
<string>To get location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>To get location</string>

回答by Carl

For Swift 2 I've replaced the respondsToSelector() check with an iOS version check. Not as elegant but it's required for Xcode 7 to give 0 errors, 0 warnings

对于 Swift 2,我用 iOS 版本检查替换了respondsToSelector() 检查。不那么优雅,但 Xcode 7 需要给出 0 个错误,0 个警告

if #available(iOS 8.0, *) {
    locationManager.requestWhenInUseAuthorization()
} else {
    locationManager.startUpdatingLocation()
}