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

Location Services not working in iOS 8

提问人:ozg 提问时间:6/5/2014 最后编辑:Alokozg 更新时间:7/27/2023 访问量:284432

问:

我的应用在 iOS 7 上运行良好,但不适用于 iOS 8 SDK。

CLLocationManager没有返回位置,而且我在“设置”->“定位服务”下也没有看到我的应用。我在谷歌上搜索了这个问题,但什么也没出现。可能出了什么问题?

Objective-C iOSS8 位置 cllocationManager

评论

0赞 ashok vadivelu 7/27/2014
还可以将其用作解决方案的参考应用 github.com/jbanford/ConstantLocationUpdates
19赞 nevan king 9/23/2014
我在这里发布了有关iOS 8中位置管理器的一些更改: nevan.net/2014/09/core-location-manager-changes-in-ios-8
2赞 lmirosevic 10/4/2014
您可以尝试使用这个库,它简化了核心位置 API 并公开了一个漂亮的基于块的界面,并规范了不同 iOS 版本之间的所有差异(完全披露:我是作者): github.com/lmirosevic/GBLocation
0赞 iOS Test 11/3/2014
我在这里找到了一些参考资料 datacalculation.blogspot.in/2014/11/......
2赞 Patrick R 4/8/2015
@nevanking先生!需要一顶皇冠!自从更改以来,我一直在与这个问题作斗争,但尚未找到如何解决它的“指南”,这对菜鸟友好。你的导游让像我这样的白痴,我自己处理问题。非常感谢您的链接。

答:

1097赞 ozg 6/5/2014 #1

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

显然,在iOS 8 SDK中,在开始位置更新之前,需要(用于后台位置)或(仅在前台时进行位置)调用。requestAlwaysAuthorizationrequestWhenInUseAuthorizationCLLocationManager

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

enter image description here

有关更广泛的信息,请查看:Core-Location-Manager-Changes-in-ios-8

评论

6赞 A B Vijay Kumar 8/3/2014
你能分享你在 Info.plist 中更新的确切价值吗?我无法在我的 Info.plist 中看到该键。我添加了它,但似乎仍然不起作用。我正在使用 Swift、iOS8 和 XCode 6 beta 4
4赞 Kendall Helmstetter Gelner 8/23/2014
@Vjay - 您必须在编辑器中编辑 Info.plist 文件,无法在 Xcode 中设置这些键(从 beta 6 开始)。
11赞 nonamelive 9/13/2014
提醒一下,如果您不想向用户显示自定义说明,只需将此键设置为空字符串即可。
7赞 Vassily 9/22/2014
您需要保留 locationManager 才能使其正常工作。因此,使 CLLocationManager 成为强属性
273赞 MobileVet 9/23/2014
我“喜欢”你没有错误,没有警告,没有日志消息,如果你遗漏了plist条目,什么都没有。基本上,Apple 已经创建了一个 API 调用,如果您没有适当的 plist 条目,该调用将不执行任何操作。感谢 @OrtwinGentz 解决这个问题。
319赞 Henry 6/5/2014 #2

我带着同样的问题拔掉了我的头发。Xcode 给出错误:

尝试在不提示的情况下启动位置更新 位置授权。必须先打电话或先打电话。MapKit-[CLLocationManager requestWhenInUseAuthorization]-[CLLocationManager requestAlwaysAuthorization]

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

将以下行添加到 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赞 Wesley Smith 6/6/2014
xcode 6 默认不添加这些键,如果您打算实现 CLLocationManager,则必须手动添加它们
1赞 Kendall Helmstetter Gelner 8/23/2014
我还必须手动添加这些,无法通过 Xcode6 中 info.plist 的 RawValues 视图添加!
1赞 MrOli3000 9/1/2014
我一直在寻找这个。我的 [CLLLocationManager authorizationStatus] 消息仅返回值 <nil>。添加上述键后,它开始返回消息输出的相应枚举。据我所知,这是一个已知的 iOS 8 错误,但多年来在我的上下文中找不到任何东西。谢谢!
4赞 Chris Chen 9/12/2014
我喜欢你输入的字符串值
1赞 arcady bob 9/29/2014
该消息将作为子消息显示在警报中,询问用户是否要共享其位置。因此,在我的应用程序中,简单地为空(空白)似乎最有意义。解释为什么要使用位置也很有意义。但是,NSLocationWhenInUseUsageDescription 的行为不符合我的预期(即,即使返回值正确,也不断获得拒绝权限)。NSLocationAlwaysUsageDescription 工作正常。
30赞 metatheoretic 6/9/2014 #3

根据 Apple 文档:

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

如果用户授予权限,则一切照常。如果他们拒绝权限,则不会通知代理位置更新。

评论

0赞 iOS Test 11/3/2014
我在 datacalculation.blogspot.in/2014/11/ 找到了简单的描述......
105赞 JKo 6/27/2014 #4

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

#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赞 progrmr 7/1/2014
比检查版本更好的方法是检查对象是否具有该选择器,例如:if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { ...
1赞 VinceFior 9/9/2014
在 Xcode 5 上构建时,我在实现 @progrmr 的解决方案时遇到了麻烦,因为它不知道方法是什么。我的另一个解决方案是在语句中使用这一行,而不是普通的方法调用:。也许这对其他人来说是显而易见的,但我花了一段时间才弄清楚。我认为在最终的 Xcode 6 发布之前,这是正确的解决方案。requestAlwaysAuthorizationif[self.locationManager performSelector:@selector(requestAlwaysAuthorization)];
2赞 progrmr 9/9/2014
正确的解决方案是使用 Xcode 6 进行构建。如果您使用 Xcode 5 进行构建,则无需请求授权,这是自动的。
0赞 VinceFior 9/10/2014
你可能说得有道理。我担心的是,当我的团队过渡到 Xcode 6 时,我希望我的代码在 Xcode 5 中编译(即使除非在 Xcode 6 中编译,否则它无法在 iOS 8 上运行)。但也许这是一个更好的工作流程,可以正常编写代码,并且在我们迁移到 Xcode 6 之前不将其合并。谢谢。
0赞 Steven Kramer 9/23/2014
@VinceFior推荐的方法是使用 SDK 定义的宏有条件地进行编译__IPHONE_OS_VERSION_MAX_ALLOWED (#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000)
7赞 hrchen 9/11/2014 #5

具有向后兼容性的解决方案:

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赞 electronix384128 9/12/2014
这是不正确的,那么 kCLAuthorizationStatusDenied 的情况呢?它跳转到 else 并开始更新不正确的位置!
0赞 Chris 9/20/2014
@BenMarten我认为这无关紧要。您应该自己处理。但是,他确实忘记将 startUpdatingLocation 添加到 if 语句中,因此在他们接受或拒绝它之后,它实际上并没有调用 startUpdateLocation。locationManager: (CLLocationManager *)manager didFailWithError: (NSError *)error
6赞 Aliaksandr Bialiauski 9/11/2014 #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+: 在 .以及其他 2 个键。NSLocationAlwaysAndWhenInUseUsageDescriptionInfo.plist

评论

0赞 electronix384128 9/12/2014
这是不正确的,那么 kCLAuthorizationStatusDenied 的情况呢?它跳转到 else 并开始更新不正确的位置!
0赞 josh 9/23/2014
这很奇怪,这对我来说很好,不允许和不允许都很好。甚至雅各布的解决方案看起来也很准确,但对我不起作用。奇怪但有效!!
0赞 Kostia Kim 2/6/2015
在请求后立即调用 [self.locationManager startUpdatingLocation] WhenInUseAuthorization 没有意义
19赞 Yinfeng 9/24/2014 #7

我的解决方案可以在 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赞 zirinisp 10/29/2014
不错的动态解决方案,可在所有应用程序中使用。不过,我会更改顺序,而不是检查iphone 8.0,而是检查位置管理器是否响应授权,然后运行authorizationstatus以获取代码。这将使它更加普遍。
0赞 Totoro 12/22/2015
也适用于 xCode 7.2。
17赞 Nits007ak 9/27/2014 #8

询问位置的旧代码在 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];
    }
}

评论

0赞 Pasan Premaratne 10/9/2014
UIAlertView 已弃用。应改用 UIAlertController。
0赞 Nits007ak 10/9/2014
是的,我知道它已被弃用,但这也会起作用。但是,是的,最好将UIAlertController用于IOS8。
51赞 neo D1 9/30/2014 #9
- (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 文件enter image description here

评论

1赞 iOS Test 11/3/2014
在 datacalculation.blogspot.in/2014/11/ 以更具描述性的方式找到了类似的解决方案......
2赞 Andrew 12/29/2014
@Hemang:根据 Apple Dev 文档:在确定应用的授权状态之前启动定位服务是安全的。尽管您可以启动定位服务,但在授权状态更改为 kCLAuthorizationStatusAuthorizedAlways 或 kCLAuthorizationStatusAuthorizedWhenInUse 之前,这些服务不会提供任何数据。
0赞 Przemysław Wrzesiński 11/23/2015
有点晚了,但我建议你隐藏你的plist文件中不相关的部分,特别是FacebookAppID
0赞 neo D1 11/23/2015
谢谢,但这只是一个虚拟的样本:)
0赞 clearlight 12/7/2016
同样重要的是,项目指向正确的 info.plist(定义键的那个)。这是在 Info.plist 文件下的项目生成设置中确定的。
13赞 user3133977 10/2/2014 #10

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

信息.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 10/11/2014
目前尚不清楚伪代码是预处理器调用还是常规调用
1赞 OxenBoxen 10/24/2014
将此添加到 constants.h 或 .pch 文件:#define IS_OS_8_OR_LATER ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
0赞 powerj1984 10/28/2014
为什么要同时要求两者,您应该添加一条注释,提及仅根据您的应用程序需求使用其中一个或另一个
0赞 CthulhuJon 2/11/2015
info.plist 部分在 Unity3d 中很容易完成,但是如果使用 unity3d,我将如何添加代码部分?哪里?
2赞 user289841 10/7/2014 #11

对于所有拥有多个 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' {} 

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

9赞 budiDino 11/11/2014 #12

在此之前,添加 iOS8 位置服务请求:[locationManager startUpdatingLocation];

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

编辑应用并添加包含将向用户显示的字符串值的键(例如,Info.plistNSLocationAlwaysUsageDescriptionWe do our best to preserve your battery life.)

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

requestAlwaysAuthorizationwith 和requestWhenInUseAuthorization

NSLocationAlwaysUsageDescription跟。NSLocationWhenInUseUsageDescription

1赞 juan Isaza 11/17/2014 #13
  1. 添加键或(后台 GPS 使用)与字符串要求在每个目标上使用 GPS。NSLocationWhenInUseUsageDescriptionNSLocationAlwaysUsageDescriptioninfo.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];
}

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

4赞 Programming Learner 11/17/2014 #14

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

NSLocationAlwaysUsageDescription in the Info.plist 

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

2赞 Prosenjit Goswami 11/18/2014 #15
        // ** 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]);

}
3赞 Derreck Dean 11/22/2014 #16

对于使用 Xamarin 的用户,我必须手动将密钥 NSLocationWhenInUseUsageDescription 添加到 info.plist,因为它在 Xamarin 5.5.3 Build 6 或 XCode 6.1 的下拉列表中不可用 - 仅在列表中,这导致它继续以静默方式失败。NSLocationUsageDescriptionCLLocationManager

9赞 Viper Chill 11/25/2014 #17

我正在开发一个升级到 iOS 8 的应用程序,但定位服务停止工作。您可能会在“调试”区域中遇到错误,如下所示:

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

我做了侵入性最小的程序。首先将条目添加到您的 info.plist:NSLocationAlwaysUsageDescription

Enter image description here

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

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

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

在此之后,调用该方法:locationManager:didChangeAuthorizationStatus:

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

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

28赞 Adarsh G J 12/17/2014 #18
- (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 文件:

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

这两个键都采用字符串

这是对您为什么需要定位服务的描述。您可以 输入一个字符串,例如“需要位置才能找出您所在的位置” 与 iOS 7 一样,可以在 InfoPlist.strings 文件中进行本地化。

enter image description here

11赞 st.derrick 2/18/2015 #19

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

首先,确保将 或 的值添加到 plist 中。NSLocationWhenInUseUsageDescriptionNSLocationAlwaysUsageDescription

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

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

0赞 Lorenzo 7/7/2015 #20

对我来说,问题是作为私有的类是私有的,这阻止了所有委托方法的调用。我想这不是一个很常见的情况,但我想我会提到它,以防万一对任何人有帮助。CLLocationManagerDelegate

0赞 AechoLiu 7/30/2015 #21

我在iOS 8.4,iPad mini 2中添加了这些键。它也有效。我没有在我的 .InfoPlist.stringsNSLocationWhenInUseUsageDescriptionInfo.plist


InfoPlist.strings

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

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

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

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

这两个键都采用一个字符串,该字符串描述了为什么 需要定位服务。您可以输入类似“位置是”位置是 需要找出你在哪里“,就像在 iOS 7 中一样,可以是 在 InfoPlist.strings 文件中本地化。


更新:

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

2赞 Marco 7/31/2015 #22

Cocoa Keys 信息始终触手可及,以便进行这些更新,这里是链接:

https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW26

享受。

5赞 Pooja Patel 9/2/2015 #23

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

评论

0赞 Carlos Ricardo 6/8/2017
NSLocationUsageDescription在 iOS8+ 上未使用
2赞 Jorge Luis Jiménez 12/30/2015 #24

我在 iOS 9 中遇到类似的错误(使用 Xcode 7 和 Swift 2):

尝试在不提示位置授权的情况下启动 MapKit 位置更新。必须先调用 -[CLLocationManager requestWhenInUseAuthorization] 或 -[CLLocationManager requestAlwaysAuthorization]。

我正在学习教程,但导师使用的是 iOS 8 和 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中: Information 属性列表:NSLocationWhenInUseUsageDescription 值:应用需要员工的位置服务器

2赞 Vinoth Vino 6/17/2017 #25

为了在 iOS 中访问用户的位置,您需要添加两个密钥,

NSLocationWhenInUseUsageDescription

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 image

4赞 Alok 10/24/2017 #26

Objective-C 过程

请按照以下说明操作:

对于iOS 11

对于iOS 11,请看这个答案: iOS 11位置访问

您需要将两个密钥添加到 plist 中并提供一条消息,如下图所示:

 1. NSLocationAlwaysAndWhenInUseUsageDescription
 2. NSLocationWhenInUseUsageDescription
 3. NSLocationAlwaysUsageDescription

Enter image description here

对于 iOS 10 及更低版本:

NSLocationWhenInUseUsageDescription

Enter image description here

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

Enter image description here

对于 iOS 10 及更低版本:

Enter image description here

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
}

评论

0赞 Alok 5/17/2018
请确保还添加了 NSLocationAlwaysUsageDescription,否则在应用商店上传时会出现错误。
0赞 Alok 5/17/2018
您的消息也应该提供信息,否则苹果将在恢复过程中拒绝该应用程序。