ChatGPT解决这个技术问题 Extra ChatGPT

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

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

CLLocationManager 不返回位置,并且我在 Settings 下看不到我的应用程序 -> 定位服务。我对这个问题进行了谷歌搜索,但没有任何结果。有什么问题?

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

J
Jean-François Fabre

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

显然在 iOS 8 SDK 中,在开始位置更新之前需要在 CLLocationManager 上调用 requestAlwaysAuthorization(用于后台位置)或 requestWhenInUseAuthorization(仅在前台时定位)。

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

https://i.stack.imgur.com/iuOzB.jpg

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


你能分享你在 Info.plist 中更新的确切价值吗?我无法在我的 Info.plist 中看到该键。我添加了它,但它似乎仍然不起作用。我正在使用 Swift、iOS8 和 XCode 6 beta 4
@Vjay - 您必须在编辑器中编辑 Info.plist 文件,不能在 Xcode 中设置这些键(从 beta 6 开始)。
提醒一下,如果您不想向用户显示自定义解释,只需将此键设置为空字符串。
您需要保留您的 locationManager 才能使其正常工作。所以让你的 CLLocationManager 成为一个强大的属性
我'喜欢'你没有收到错误,没有警告,没有日志消息,如果你遗漏了 plist 条目,什么都没有。基本上,如果您没有适当的 plist 条目,Apple 已经创建了一个 API 调用,它什么都不做。感谢@OrtwinGentz 解决了这个问题。
U
User1

我正在用同样的问题拔头发。 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 可能会为这些键添加默认条目,但尚未确认。

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


xcode 6 默认不添加这些键,如果你打算实现 CLLocationManager 你必须手动添加它们
我还必须手动添加这些,无法通过 Xcode6 中 info.plist 的 RawValues 视图添加!
我一直在寻找这个。我的 [CLLLocationManager authorizationStatus] 消息仅返回 值。添加上述键后,它开始返回消息输出的相应枚举。根据我的发现,这是一个已知的 iOS 8 错误,但多年来在我的上下文中找不到任何东西。谢谢一米!
我喜欢你输入的字符串值
该消息将显示为警报中的子消息,询问用户是否愿意分享他们的位置。因此,简单地为空(空白)似乎在我的应用程序中最有意义。解释为什么要使用位置也是有道理的。但是, NSLocationWhenInUseUsageDescription 对我来说并没有像预期的那样运行(即,即使返回值是正确的,也一直被拒绝许可)。 NSLocationAlwaysUsageDescription 工作正常。
J
JKo

为确保向后兼容 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];

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


}

https://i.stack.imgur.com/bQcRQ.png


datacalculation.blogspot.in/2014/11/… 以更具描述性的方式找到了类似的解决方案
@Hemang:根据Apple Dev Documentation:在确定您的应用程序的授权状态之前启动位置服务是安全的。尽管您可以启动位置服务,但这些服务在授权状态更改为 kCLAuthorizationStatusAuthorizedAlways 或 kCLAuthorizationStatusAuthorizedWhenInUse 之前不会传递任何数据。
有点晚了,但我建议你隐藏你的 plist 文件的不相关部分,尤其是 FacebookAppID
谢谢,但这只是一个虚拟样本:)
项目指向正确的 info.plist(定义密钥的那个)也很重要。这是在 Info.plist 文件下的项目构建设置中确定的。
C
Cœur

根据苹果文档:

https://developer.apple.com/documentation/corelocation/requesting_permission_to_use_location_services

https://developer.apple.com/documentation/corelocation/cllocationmanager/1620562-requestwheninuseauthorization

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

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


我在 datacalculation.blogspot.in/2014/11/… 找到了简单的描述
C
Community
- (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 文件中进行本地化。

https://i.stack.imgur.com/aQuZf.png


P
Peter Mortensen

我可以在 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];

不错的动态解决方案,可在所有应用程序中使用。我会更改订单,而不是检查 iphone 8.0,我会检查位置管理器是否响应授权,然后运行授权状态以获取代码。这将使其更具普遍性。
也适用于 xCode 7.2。
P
Peter Mortensen

询问位置的旧代码在 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。
是的,我知道它已被弃用,但这也可以。但是是的,最好将 UIAlertController 用于 IOS8。
b
byJeevan

在 iOS 8 中,你需要做两件额外的事情来让位置工作:向你的 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];
}

目前尚不清楚您的伪代码是预处理器调用还是常规调用
将此添加到您的 constants.h 或 .pch 文件中:#define IS_OS_8_OR_LATER ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
为什么你会要求两者,你应该添加一个评论只提到根据你的应用程序需要使用一个或另一个
info.plist 部分在 Unity3d 中很容易做到,但是如果使用 unity3d 我将如何添加代码部分?在哪里 ?
s
st.derrick

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

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

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

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


P
Peter Mortensen

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

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

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

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

requestAlwaysAuthorizationrequestWhenInUseAuthorization

NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription


P
Peter Mortensen

我正在开发一个升级到 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:

https://i.stack.imgur.com/N4M21.png

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

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

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

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

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

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


h
hrchen

向后兼容的解决方案:

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 键


这是不正确的,kCLAuthorizationStatusDenied 的情况呢?它跳转到 else 并开始更新不正确的位置!
@BenMarten 我认为这无关紧要。您应该使用 locationManager: (CLLocationManager *)manager didFailWithError: (NSError *)error 自己处理。但是,他确实忘记将 startUpdatingLocation 添加到 if 语句中,因此在他们接受或拒绝它之后,它实际上并没有调用 startUpdateLocation。
b
byJeevan

不产生 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];
}

在您的 Info.plist 中设置 NSLocationWhenInUseUsageDescription 键。

对于 iOS 版本 11.0+:在您的 Info.plist 中设置 NSLocationAlwaysAndWhenInUseUsageDescription 键。连同其他 2 个键。


这是不正确的,kCLAuthorizationStatusDenied 的情况呢?它跳转到 else 并开始更新不正确的位置!
这很奇怪,这对我来说很好,在允许和不允许的情况下都很好。即使雅各布解决方案看起来很准确,但对我不起作用。奇怪但有效!
在 requestWhenInUseAuthorization 之后立即调用 [self.locationManager startUpdatingLocation] 没有意义
P
Pooja Patel

这是 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+ 上不使用
P
Programming Learner

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

NSLocationAlwaysUsageDescription in the Info.plist 

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


A
Alok

Objective-C 过程遵循以下说明:

对于 iOS-11 对于 iOS 11,请查看此答案:iOS 11 location access

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

 1. NSLocationAlwaysAndWhenInUseUsageDescription 
 2. NSLocationWhenInUseUsageDescription
 3. NSLocationAlwaysUsageDescription

https://i.stack.imgur.com/bXyB3.png

NSLocationWhenInUseUsageDescription

https://i.stack.imgur.com/JIwZ0.png

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

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

 1. NSLocationAlwaysAndWhenInUseUsageDescription 
 2. NSLocationWhenInUseUsageDescription
 3. NSLocationAlwaysUsageDescription

https://i.stack.imgur.com/cHdfe.png

https://i.stack.imgur.com/utuWG.png

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,否则在应用商店上传时会出错。
您的消息也应该提供信息,否则苹果将在审查过程中拒绝该应用程序。
D
Derreck Dean

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


P
Prosenjit Goswami
        // ** 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]);

}

P
Peter Mortensen

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

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


M
Marco
J
Jorge Luis Jiménez

我在 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 值:应用程序需要员工的位置服务器


V
Vinoth Vino

为了访问用户在 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>

请参见下图。

https://i.stack.imgur.com/LZ1df.png


j
juan Isaza

添加键 NSLocationWhenInUseUsageDescription 或 NSLocationAlwaysUsageDescription(背景 GPS 使用),字符串要求在每个目标的每个 info.plist 上使用 GPS。通过运行请求许可: [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 的问题。


L
Lorenzo

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


C
Community

我在 iOS 8.4、iPad mini 2 中的 InfoPlist.strings 中添加了这些键。 它也可以。我没有在我的 Info.plist 中设置任何键,例如 NSLocationWhenInUseUsageDescription

InfoPlist.strings:

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

Base on this thread,它说,as in iOS 7,可以在 InfoPlist.strings 中本地化。在我的测试中,这些键可以直接在文件 InfoPlist.strings 中配置。

因此,您需要做的第一件事是将 > 以下键中的一个或两个添加到您的 Info.plist 文件中: NSLocationWhenInUseUsageDescription NSLocationAlwaysUsageDescription 这两个键都带有一个字符串,该字符串描述了您需要位置服务的原因。您可以输入一个字符串,如“需要位置才能找出您所在的位置”,与 iOS 7 一样,可以在 InfoPlist.strings 文件中进行本地化。

更新:

我认为 @IOS's method is better. 将具有空值的键添加到 Info.plist 并将本地化字符串添加到 InfoPlist.strings