定位服务在iOS 8中不起作用


608

我在iOS 7上运行良好的应用无法与iOS 8 SDK一起使用。

CLLocationManager不会返回位置,并且在“设置” ->“ 位置服务”下也看不到我的应用程序。我对此问题进行了Google搜索,但没有发现任何问题。有什么事吗


您还可以将其用作解决方案的参考应用程序github.com/jbanford/ConstantLocationUpdates
ashok vadivelu 2014年

19
我在这里发布了有关iOS 8中位置管理器的一些更改:nevan.net/2014/09/core-location-manager-changes-in-ios-8
nevan king

2
您可以尝试使用此库,该库简化了Core Location API,并公开了基于块的漂亮界面,并规范了不同iOS版本之间的所有差异(完整披露:我是作者):github.com/lmirosevic/GBLocation
lms

我发现了一些参考这里datacalculation.blogspot.in/2014/11/...
iOS的测试

2
@nevanking您,先生!需要皇冠!自从更改以来,我一直在与这个问题作斗争,但还没有找到解决该问题的“指南”,那是菜鸟友好的。非常感谢您提供的链接。
Patrick R

Answers:


1086

我最终解决了自己的问题。

显然,在iOS 8 SDK中,需要在开始位置更新之前调用requestAlwaysAuthorization(用于背景位置)或requestWhenInUseAuthorization(仅用于前景位置)CLLocationManager

还需要输入NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription键入Info.plist要在提示中显示的消息。添加这些解决了我的问题。

enter image description here

希望它可以帮助别人。

编辑:有关更多信息,请参阅:Core-Location-Manager-Changes-in-ios-8


6
您可以共享在Info.plist中更新的确切评估者吗?我无法在我的Info.plist中看到该密钥。我添加了它,但它似乎仍然不起作用。我正在使用Swift,iOS8和XCode 6 beta 4
Vijay Kumar AB

4
@Vjay-您必须在编辑器中编辑Info.plist文件,无法在Xcode中设置这些键(自beta 6起)。
Kendall Helmstetter Gelner 2014年

11
提醒您,如果您不想向用户显示自定义说明,只需将此键设置为空字符串即可。
消极的

7
您需要保留locationManager才能使其正常工作。因此,请将您的CLLocationManager设为强大的属性
Vassily 2014年

273
我“爱”您没有错误,没有警告,没有日志消息,如果您没有列出plist条目,则什么也没有。基本上,Apple创建了一个API调用,如果您没有适当的plist条目,则该API不会。感谢@OrtwinGentz弄清楚了这一点。
MobileVet

314

我也遇到同样的问题。Xcode给您错误:

尝试启动MapKit位置更新而没有提示位置授权。必须先致电-[CLLocationManager requestWhenInUseAuthorization]-[CLLocationManager requestAlwaysAuthorization]先致电。

但是,即使您实现上述方法之一,也不会提示用户,除非info.plist中有NSLocationAlwaysUsageDescription或的条目NSLocationWhenInUseUsageDescription

将以下行添加到info.plist中,其中字符串值表示您需要访问用户位置的原因

<key>NSLocationWhenInUseUsageDescription</key>
<string>This application requires location services to work</string>

<key>NSLocationAlwaysUsageDescription</key>
<string>This application requires location services to work</string>

我认为自从我在Xcode 5中启动此项目以来,这些条目可能已经丢失了。我猜Xcode 6可能会为这些键添加默认条目,但尚未确认。

您可以在此处找到有关这两个设置的更多信息


13
xcode 6默认情况下不会添加这些键,如果您打算实现CLLocationManager,则必须手动添加它们
Wesley Smith

1
我还必须手动添加这些,无法通过Xcode6中的info.plist的RawValues视图添加!
Kendall Helmstetter Gelner 2014年

1
我为此永远寻找。我的[CLLLocationManagerauthorizationStatus]消息仅返回值<nil>。添加以上键后,它开始返回消息输出的相应枚举。从我发现的结果来看,这是一个已知的iOS 8错误,但是在我的情境下,多年来一直找不到。谢谢你!
MrOli3000 2014年

4
我喜欢您输入的字符串值
Chris Chen

1
该消息将显示为“警报”中的子消息,询问用户是否要共享其位置。因此,在我的应用程序中,最简单的选择是空白(空)。解释为什么要使用位置也很有意义。但是,NSLocationWhenInUseUsageDescription的行为对我而言并不理想(即,即使返回值正确,也一直拒绝获得许可)。NSLocationAlwaysUsageDescription工作正常。
arcady bob 2014年

104

为了确保它与iOS 7向后兼容,您应该检查用户运行的是iOS 8还是iOS7。例如:

#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)

//In ViewDidLoad
if(IS_OS_8_OR_LATER) {
   [self.locationManager requestAlwaysAuthorization];
}

[self.locationManager startUpdatingLocation];

164
比检查版本更好的方法是检查对象是否具有该选择器,例如: if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { ...
progrmr 2014年

1
在Xcode 5上构建时,我仅实现@progrmr的解决方案就遇到了麻烦,因为它不知道requestAlwaysAuthorization方法是什么。我的其他解决方案是在if语句中使用此行,而不是常规方法调用:[self.locationManager performSelector:@selector(requestAlwaysAuthorization)];。也许这对其他人来说是显而易见的,但是花了我一段时间才弄清楚。我认为这是正确的解决方案,直到最终的Xcode 6发布。
VinceFior 2014年

2
正确的解决方案是使用Xcode 6进行构建。如果使用Xcode 5进行构建,则不需要请求授权,这是自动的。
progrmr 2014年

您可能有一点。我的担心是,当我的团队过渡到Xcode 6时,我希望我的代码可以在Xcode 5中编译(即使它不能在iOS 8上运行,除非在Xcode 6中进行编译),但是也许可以更好地工作,以正常方式编写代码,并且在我们移至Xcode 6之前,不要将其合并。
VinceFior 2014年

@VinceFior推荐的方法是使用SDK定义的宏__IPHONE_OS_VERSION_MAX_ALLOWED#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000)有条件地进行编译
Steven Kramer

50
- (void)startLocationManager
{
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.distanceFilter = kCLDistanceFilterNone; //whenever we move
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;

    [locationManager startUpdatingLocation];
    [locationManager requestWhenInUseAuthorization]; // Add This Line


}

并到您的info.plist文件 在此处输入图片说明



2
@Hemang:根据Apple Dev文档:在确定应用程序的授权状态之前,可以安全地启动位置服务。尽管您可以启动定位服务,但是在授权状态更改为kCLAuthorizationStatusAuthorizedAlways或kCLAuthorizationStatusAuthorizedWhenInUse之前,这些服务不会传递任何数据。
安德鲁(Andrew)

有点晚了,但我建议你隐藏你的plist文件的不相关部分,尤其是FacebookAppID
普热Wrzesiński

谢谢,但是那只是一个虚拟样品:)
neo D1

该项目指向正确的 info.plist(定义键的那个)也很重要。这由Info.plist文件下的项目构建设置确定。
clearlight's

30

根据Apple文档:

从iOS 8开始,您的应用程序的Info.plist文件中必须存在NSLocationWhenInUseUsageDescriptionNSLocationAlwaysUsageDescription键值。然后,还需要通过致电[self.myLocationManager requestWhenInUseAuthorization][self.myLocationManager requestAlwaysAuthorization]根据您的需要在注册位置更新之前请求用户的许可。您在Info.plist中输入的字符串将显示在随后的对话框中。

如果用户授予许可,则照常营业。如果他们拒绝许可,则不会将位置更新通知给代理。


我在这里找到了简单的描述,位于datacalculation.blogspot.in/2014/11/…–
iOS测试

28
- (void)viewDidLoad
{

    [super viewDidLoad];
    self.locationManager = [[CLLocationManager alloc] init];

    self.locationManager.delegate = self;
    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]){
        NSUInteger code = [CLLocationManager authorizationStatus];
        if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) {
            // choose one request according to your business.
            if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
                [self.locationManager requestAlwaysAuthorization];
            } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
                [self.locationManager  requestWhenInUseAuthorization];
            } else {
                NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription");
            }
        }
    }
    [self.locationManager startUpdatingLocation];
}

>  #pragma mark - CLLocationManagerDelegate

    - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
    {
        NSLog(@"didFailWithError: %@", error);
        UIAlertView *errorAlert = [[UIAlertView alloc]
                                   initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [errorAlert show];
    }

    - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
    {
        NSLog(@"didUpdateToLocation: %@", newLocation);
        CLLocation *currentLocation = newLocation;

        if (currentLocation != nil) {
            longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
            latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
        }
    }

在iOS 8中,您需要执行两项额外的操作来使位置正常工作:向Info.plist添加一个密钥,并向位置管理器请求授权以要求其启动。有两个用于新位置授权的Info.plist键。这些键之一或全部是必需的。如果两个键都不存在,则可以调用startUpdatingLocation,但是位置管理器实际上不会启动。它也不会向代理发送失败消息(因为它从未启动,所以不会失败)。如果您添加一个或两个密钥,但是忘记显式地请求授权,它也会失败。因此,您需要做的第一件事是将以下两个键中的一个或两个添加到Info.plist文件中:

  • NSLocationWhenInUseUsesDescription
  • NSLocationAlwaysUsageDescription

这两个键都带一个字符串

这是为什么需要定位服务的说明。您可以输入一个字符串,例如“需要位置才能找到自己的位置”,就像在iOS 7中一样,可以在InfoPlist.strings文件中进行本地化。

在此处输入图片说明


19

我的解决方案可以在Xcode 5中进行编译:

#ifdef __IPHONE_8_0
    NSUInteger code = [CLLocationManager authorizationStatus];
    if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) {
        // choose one request according to your business.
        if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
            [self.locationManager requestAlwaysAuthorization];
        } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
            [self.locationManager  requestWhenInUseAuthorization];
        } else {
            NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription");
        }
    }
#endif
    [self.locationManager startUpdatingLocation];

2
不错的动态解决方案,可在所有应用中使用。我会更改顺序,而不是检查iphone 8.0,而是检查位置管理器是否响应授权,然后运行授权状态来获取代码。这将使其更加通用。
zirinisp 2014年

也在xCode 7.2上工作。
龙猫

17

询问位置的旧代码在iOS 8中不起作用。您可以尝试使用以下方法进行位置授权:

- (void)requestAlwaysAuthorization
{
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];

    // If the status is denied or only granted for when in use, display an alert
    if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status ==        kCLAuthorizationStatusDenied) {
        NSString *title;
        title = (status == kCLAuthorizationStatusDenied) ? @"Location services are off" :   @"Background location is not enabled";
        NSString *message = @"To use background location you must turn on 'Always' in the Location Services Settings";

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
                                                            message:message
                                                           delegate:self
                                                  cancelButtonTitle:@"Cancel"
                                                  otherButtonTitles:@"Settings", nil];
        [alertView show];
    }
    // The user has not enabled any location services. Request background authorization.
    else if (status == kCLAuthorizationStatusNotDetermined) {
        [self.locationManager requestAlwaysAuthorization];
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        // Send the user to the Settings for this app
        NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        [[UIApplication sharedApplication] openURL:settingsURL];
    }
}

UIAlertView已被弃用。您应该改用UIAlertController。
Pasan Premaratne,2014年

是的,我知道它已被弃用,但这也行得通。但是是的,最好对IOS8使用UIAlertController。
Nits007ak 2014年

12

在iOS 8中,您需要做两项额外的工作才能使位置正常工作:向Info.plist添加一个密钥,并向位置管理器请求授权以要求其启动

info.plist:

<key>NSLocationUsageDescription</key>
<string>I need location</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>I need location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>I need location</string>

将此添加到您的代码

if (IS_OS_8_OR_LATER)
{
    [locationmanager requestWhenInUseAuthorization];

    [locationmanager requestAlwaysAuthorization];
}

1
目前尚不清楚您的伪代码是预处理程序调用还是常规调用
El Dude 2014年

1
将此添加到您的constants.h或.pch文件中:#define IS_OS_8_OR_LATER([[UIDevice currentDevice] .systemVersion floatValue]> = 8.0)
OxenBoxen 2014年

为什么你会要求这两个,你应该添加评论仅提及使用你的应用需要一个或其他依赖
powerj1984

info.plist部分很容易在Unity3d中完成,但是如果使用unity3d我该如何添加代码部分呢?在哪
CthulhuJon 2015年

11

Swift开发人员的一个常见错误:

首先,请确保您为NSLocationWhenInUseUsageDescription或的值添加了一个值NSLocationAlwaysUsageDescription

如果您仍然没有看到弹出窗口要求授权,请查看是否将该行var locationManager = CLLocationManager()放入View Controller的viewDidLoad方法中。如果您这样做,那么即使您致电locationManager.requestWhenInUseAuthorization(),也不会显示任何内容。这是因为在执行viewDidLoad之后,会释放(清除)locationManager变量。

解决方案是将行定位var locationManager = CLLocationManager()在class方法的顶部。


9

在之前[locationManager startUpdatingLocation];,添加一个iOS8定位服务请求:

if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
    [locationManager requestAlwaysAuthorization];

编辑应用程序Info.plist并添加NSLocationAlwaysUsageDescription将显示给用户的字符串值的键(例如,We do our best to preserve your battery life.

如果您的应用仅在打开时需要位置服务,请替换:

requestAlwaysAuthorizationrequestWhenInUseAuthorization

NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription


9

我正在开发一个已升级到iOS 8的应用程序,但位置服务停止工作。您可能会在Debug区域中出现错误,如下所示:

Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.

我进行了最少干扰的程序。首先将NSLocationAlwaysUsageDescription条目添加到您的info.plist中:

在此处输入图片说明

注意,我没有填写此键的值。这仍然有效,并且我不担心,因为这是内部应用程序。另外,已经有一个标题要求使用位置服务,因此我不想做任何多余的事情。

接下来,我为iOS 8创建了一个条件:

if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
    [_locationManager requestAlwaysAuthorization];
}

之后,该locationManager:didChangeAuthorizationStatus:方法被调用:

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:  (CLAuthorizationStatus)status
{
    [self gotoCurrenLocation];
}

现在一切正常。与往常一样,请查阅文档


7

向后兼容的解决方案:

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

在Info.plist中设置NSLocationWhenInUseUsageDescription键


2
这是不正确的,那么kCLAuthorizationStatusDenied情况又如何呢?它跳到别的位置并开始更新不正确的位置!
electronicix384128

@BenMarten我认为这不重要。您应该自己处理locationManager: (CLLocationManager *)manager didFailWithError: (NSError *)error。但是,他确实忘记将startUpdatingLocation添加到if语句中,因此在他们接受或拒绝它之后,它实际上并没有调用startUpdateLocation。
克里斯

6

具有向后兼容性的解决方案,不会产生Xcode警告:

SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
  [self.locationManager respondsToSelector:requestSelector]) {
((void (*)(id, SEL))[self.locationManager methodForSelector:requestSelector])(self.locationManager, requestSelector);
  [self.locationManager startUpdatingLocation];
} else {
  [self.locationManager startUpdatingLocation];
}

设置NSLocationWhenInUseUsageDescriptionInfo.plist

对于iOS版本11.0及更高版本:安装NSLocationAlwaysAndWhenInUseUsageDescription在你的钥匙Info.plist。以及其他2个键。


这是不正确的,那么kCLAuthorizationStatusDenied情况又如何呢?它跳到别的位置并开始更新不正确的位置!
electronicix384128

这很奇怪,这对我来说很好用,对允许和不允许都没有很好的配合。奇怪,但工作!!!
2014年

在requestWhenInUseAuthorization没有意义后立即调用[self.locationManager startUpdatingLocation]
Kostia Kim

5

这是ios 8的问题将其添加到您的代码中

if (IS_OS_8_OR_LATER)
{
    [locationmanager requestWhenInUseAuthorization];

    [locationmanager requestAlwaysAuthorization];
}

并到info.plist:

 <key>NSLocationUsageDescription</key>
 <string>I need location</string>
 <key>NSLocationAlwaysUsageDescription</key>
 <string>I need location</string>
 <key>NSLocationWhenInUseUsageDescription</key>
 <string>I need location</string>

NSLocationUsageDescription在iOS8 +上未使用
Carlos Ricardo

4

要访问iOS 8中的用户位置,您必须添加,

NSLocationAlwaysUsageDescription in the Info.plist 

这将要求用户获得其当前位置的权限。


4

Objective-C程序请 遵循以下指示:

对于iOS-11 对于iOS 11,请查看以下答案:iOS 11位置访问权限

需要在plist中添加两个键,并提供如下图所示的消息:

 1. NSLocationAlwaysAndWhenInUseUsageDescription 
 2. NSLocationWhenInUseUsageDescription
 3. NSLocationAlwaysUsageDescription

在此处输入图片说明 对于iOS-10及以下版本:

NSLocationWhenInUseUsageDescription

在此处输入图片说明

locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
if([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){
    [locationManager requestWhenInUseAuthorization];
}else{
    [locationManager startUpdatingLocation];
} 

委托方法

#pragma mark - Lolcation Update 
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"didFailWithError: %@", error);
    UIAlertView *errorAlert = [[UIAlertView alloc]
                               initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [errorAlert show];
}
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    switch (status) {
        case kCLAuthorizationStatusNotDetermined:
        case kCLAuthorizationStatusRestricted:
        case kCLAuthorizationStatusDenied:
        {
            // do some error handling
        }
            break;
        default:{
            [locationManager startUpdatingLocation];
        }
            break;
    }
}
- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray *)locations
{
    CLLocation *location = [locations lastObject];
    userLatitude =  [NSString stringWithFormat:@"%f", location.coordinate.latitude] ;
    userLongitude =  [NSString stringWithFormat:@"%f",location.coordinate.longitude];
    [locationManager stopUpdatingLocation];
}

快速程序

请遵循以下指示:

对于iOS-11 对于iOS 11,请查看以下答案:iOS 11位置访问权限

需要在plist中添加两个键,并提供如下图所示的消息:

 1. NSLocationAlwaysAndWhenInUseUsageDescription 
 2. NSLocationWhenInUseUsageDescription
 3. NSLocationAlwaysUsageDescription

在此处输入图片说明 对于iOS-10及以下版本:

在此处输入图片说明

import CoreLocation
class ViewController: UIViewController ,CLLocationManagerDelegate {
var locationManager = CLLocationManager()

//MARK- Update Location 
func updateMyLocation(){
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
    if locationManager.respondsToSelector(#selector(CLLocationManager.requestWhenInUseAuthorization)){
       locationManager.requestWhenInUseAuthorization()
    }
    else{
        locationManager.startUpdatingLocation()
    }
}

委托方法

//MARK: Location Update
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
    NSLog("Error to update location :%@",error)
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
    switch status {
    case .NotDetermined: break
    case .Restricted: break
    case .Denied:
            NSLog("do some error handling")
        break
    default:
        locationManager.startUpdatingLocation()
    }
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
     let location = locations.last! as CLLocation
    var latitude = location.coordinate.latitude
    var longitude = location.coordinate.longitude

}

请确保还添加了NSLocationAlwaysUsageDescription,否则在应用商店上载时会出现错误。
阿洛克

您的消息还应该提供信息,否则苹果将在重新启动过程中拒绝该应用程序。
阿洛克

3

对于使用Xamarin的用户,我必须NSLocationWhenInUseUsageDescription手动将密钥添加到info.plist中,因为Xamarin 5.5.3 Build 6或XCode 6.1的下拉列表中均不提供该密钥-仅存 NSLocationUsageDescription在于列表中,这导致CLLocationManager继续默默地失败。


2
        // ** Don't forget to add NSLocationWhenInUseUsageDescription in MyApp-Info.plist and give it a string

        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;
        // Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
        if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
            [self.locationManager requestWhenInUseAuthorization];
        }
        [self.locationManager startUpdatingLocation];


    // Location Manager Delegate Methods    
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
        NSLog(@"%@", [locations lastObject]);

}

2

一个拥有多个Info.plist文件的所有人的小帮手...

find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c 'Add NSLocationWhenInUseUsageDescription string' {} 

它将所需的标记添加到当前目录(和子文件夹)中的所有Info.plist文件中。

另一个是:

find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c 'Set NSLocationWhenInUseUsageDescription $YOURDESCRIPTION' {} 

它将您的描述添加到所有文件。



2

我在iOS9(使用Xcode 7和Swift 2)中遇到了类似的错误: 尝试启动MapKit位置更新而没有提示位置授权。必须首先调用-[CLLocationManager requestWhenInUseAuthorization]或-[CLLocationManager requestAlwaysAuthorization]。 我正在关注一个教程,但导师正在使用iOS8和Swift 1.2。Xcode 7和Swift 2进行了一些更改,我找到了这段代码,它对我来说很好用(如果有人需要帮助):

import UIKit
import MapKit
import CoreLocation

class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

    // MARK: Properties
    @IBOutlet weak var mapView: MKMapView!

    let locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()
        self.mapView.showsUserLocation = true

    }

    // MARK: - Location Delegate Methods

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location = locations.last
        let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1))
        self.mapView.setRegion(region, animated: true)
    }

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        print("Errors: " + error.localizedDescription)
    }
}

最后,我将其放在info.plist中:信息属性列表:NSLocationWhenInUseUsageDescription 值:应用需要人员的位置服务器


2

为了在iOS中访问用户位置。您需要添加两个键

NSLocationWhenInUseUsesDescription

NSLocationAlwaysUsageDescription

到Info.plist文件中。

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Because I want to know where you are!</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>Want to know where you are!</string>

参见下图。

Info.plist图片


1
  1. 要求在每个目标的每个目标上使用GPS NSLocationWhenInUseUsageDescriptionNSLocationAlwaysUsageDescription字符串添加密钥或(使用背景GPS)info.plist

  2. 通过运行以下命令寻求许可:

    [self initLocationManager:locationManager];

在哪里initLocationManager

// asks for GPS authorization on iOS 8
-(void) initLocationManager:(CLLocationManager *) locationManager{

    locationManager = [[CLLocationManager alloc]init];

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

请记住,如果info.plist每个目标上的按键都不在,则应用不会询问用户。在if提供兼容的iOS 7的respondsToSelector:方法保证未来的兼容性,而不仅仅是解决问题为iOS 7和8。


0

对我来说,问题在于,那个类CLLocationManagerDelegate是私有的,这阻止了所有委托方法的调用。猜猜这不是很常见的情况,但是我想我提一下是为了防止t帮助任何人。


0

InfoPlist.stringsiOS 8.4,iPad mini 2中添加了这些密钥它也可以工作。我没有设置任何按键,比如NSLocationWhenInUseUsageDescription,在我的Info.plist


InfoPlist.strings

"NSLocationWhenInUseUsageDescription" = "I need GPS information....";

它说,基于该线程as in iOS 7可以在InfoPlist.strings中进行本地化。在我的测试中,这些键可以直接在file中配置InfoPlist.strings

因此,您需要做的第一件事是在Info.plist文件中添加一个或以下两个键:

  • NSLocationWhenInUseUsesDescription
  • NSLocationAlwaysUsageDescription

这两个键都带有一个字符串,该字符串描述了为什么需要定位服务。您可以输入类似“需要位置才能找到您所在的位置”之类的字符串,就像在iOS 7中一样,可以在InfoPlist.strings文件中进行本地化。


更新:

我认为@IOS的方法更好。将key添加为Info.plist空值,并将本地化的字符串添加到InfoPlist.strings

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.