简体   繁体   English

CLLocationManager授权问题iOS 8

[英]CLLocationManager authorization issue iOS 8

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

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. 我试过更新我的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. 我确信那是问题因为我在我的控制台上没有获得授权。

Any help? 有帮助吗?

It's an iOS 8 related issue. 这是iOS 8相关问题。 You have to put NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription keys in your .plist file (value may be an additional message that will be presented in location alert). 您必须在.plist文件中放置NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription键(值可能是将在位置警报中显示的其他消息)。 These keys are required in iOS 8. iOS 8中需要这些键。

How it's said in Apple guidelines : 如何在Apple指南中说:

This key is required when you use the requestAlwaysAuthorization method of the CLLocationManager class to request authorization for location services. 当您使用CLLocationManager类的requestAlwaysAuthorization方法请求位置服务的授权时,此密钥是必需的。 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. 如果此密钥不存在且您调用requestAlwaysAuthorization方法,系统将忽略您的请求并阻止您的应用使用位置服务。

I had struggled with a similar issue, which persisted even after adding the NSLocationAlwaysUsageDescription/NSLocationWhenInUseUsageDescription keys to the plist. 我一直在努力解决类似的问题,即使在将plLocationAlwaysUsageDescription / NSLocationWhenInUseUsageDescription键添加到plist之后,该问题仍然存在。

Eventually, I added the "Privacy - Location Usage Description" key to the plist (in addition to the new keys) and voila, it worked! 最后,我添加了“隐私 - 位置使用说明”键到plist(除了新键),瞧,它工作了! 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中删除“隐私 - 位置使用说明”键并继续成功请求授权。

iOS 8 has changed location authorization strategy. iOS 8改变了位置授权策略。 Solution with backward compatibility: 向后兼容的解决方案:

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键

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 NSLocationWhenInUseUsageDescription key to my info.plist. 我的应用程序不需要在后台运行,因此我将NSLocationWhenInUseUsageDescription键添加到我的info.plist中。

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. 它必须匹配我在plist中放置的值。 I guess you could put both, but I dunno. 我想你可以放两个,但我不知道。 I didn't need to. 我不需要。

The project is here . 这个项目在这里 Most of the work (not much) is in the BMLTAppDelegate.m file. 大部分工作(不多)都在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中运行。他们会做我最初做过的事情:在模拟器中快速运行,注意挂起,然后将其归结为beta bug。

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. 现在,我有一个不同的问题:我的所有应用程序都已修复,但当我尝试将应用程序上传到App Store时,Xcode崩溃了。 I have a RADAR open on it. 我打开了RADAR。

Xcode 6 is kinda creaky. Xcode 6有点吱吱作响。 I expect a patch to come out pretty quickly. 我希望补丁能够很快出现。

Since I do not like to edit the plist directly, I always grant autorisation by using the UI. 由于我不喜欢直接编辑plist,我总是通过使用UI来授予autorisation。

在此输入图像描述

The Dutch texts "Toegang is nodig" and "Toegang is noodzakelijk" are displayed in the PopUp in which the used grants access. 荷兰文本“Toegang is nodig”和“Toegang is noodzakelijk”显示在PopUp中,其中使用的授权访问。 You can change these to any text you like. 您可以将这些更改为您喜欢的任何文本。

Simply add to plist source, 只需添加到plist源,

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

For Swift 2 I've replaced the respondsToSelector() check with an iOS version check. 对于Swift 2,我已经用iOS版本检查替换了respondsToSelector()检查。 Not as elegant but it's required for Xcode 7 to give 0 errors, 0 warnings 不是那么优雅,但是Xcode 7需要提供0个错误,0个警告

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

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

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