如何在iOS 8中获取当前位置的纬度和经度?

7

我的问题是在 iOS 8 上无法获取当前位置的纬度和经度。我尝试在 .plist 文件中设置密钥用于 iOS 8,但是没有调用这个方法 - didUpdateToLocation: 请帮忙解决这个问题。

我的代码是:

- (void)viewDidLoad

{

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

if(IS_OS_8_OR_LATER) {
    //[self.locationManager requestWhenInUseAuthorization];
    [self.locationManager requestWhenInUseAuthorization];
    [self.locationManager startUpdatingLocation];
}

}


iOS 是否要求您授予位置权限?如果您在模拟器中进行测试,是否设置了测试位置? - fluidsonic
请注意 - 不要检查iOS版本。请检查所需方法是否存在。 - rmaddy
是的,我在模拟器中进行了测试,并在.plist文件中设置了这两个键:NSLocationWhenInUseUsageDescription和NSLocationAlwaysUsageDescription。 - Dhananjay Patel
请查看此链接http://rshankar.com/get-your-current-address-in-swift/,虽然它是用Swift编写的,但您可以检查权限等。 - Kundan
1个回答

35
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
-(void)viewDidLoad
{  
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];

self.locationManager.delegate = self;
if(IS_OS_8_OR_LATER){
    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文件中本地化。

1
不要使用IS_OS_8_OR_LATER。有适当的方法来检查API是否可用。 - rmaddy
@TheCodingArt根本不需要检查版本。正确的方法是使用respondsToSelector:等方式来检查API。 - rmaddy
@rmaddy...那其实是一种非常糟糕的方法。这绝不是一种适当的方式(特别是在今天的Swift时代)。respondsToSelector有普遍假设,忽略私有和公共实现以及其他事情。你应该绝对检查版本而不是依赖它。 - TheCodingArt
无论采用何种方法,我想指出的是,如果您需要检查版本,则添加自定义宏不仅不可靠(因为systemVersion并不总是反映正确的iOS子版本),而且也是多余的。 - TheCodingArt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接