didUpdateLocations没有被调用

37

我正在尝试获取我的当前位置,但是didUpdateLocations中的断点从未被调用。

LocationManager:

locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager setDesiredAccuracy:kCLDistanceFilterNone];
[locationManager startUpdatingLocation];

委托方法:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;

我确认了位置服务已启用并授权。

为什么locationManager委托方法没有像应该那样被调用?


1
几分钟前我也遇到了同样的问题,我没有执行 [[CLLocationManager alloc] init];。这是帮助我的链接 - nupac
尝试删除此行代码:[locationManager setDesiredAccuracy:kCLDistanceFilterNone]; 因为你已经两次调用了 setDesiredAccuracy,并将 locationManager 设置为属性。 - Julian
8个回答

69
此外,在iOS8中,您需要两个额外的东西:
1. 将键添加到您的Info.plist并请求授权以启动位置管理器。
  • NSLocationWhenInUseUsageDescription

  • NSLocationAlwaysUsageDescription

2. 您需要请求相应位置方法的授权。
  • [self.locationManager requestWhenInUseAuthorization]

  • [self.locationManager requestAlwaysAuthorization]

代码示例:
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];

来源:http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/

iOS 8中的核心位置管理器发生了一些变化。在iOS 8之前,当应用程序在后台运行时,位置更新事件会以相同的频率继续发生,而在iOS 8中,这种情况已经改变。现在,在应用程序进入后台模式后,系统会根据用户的移动和时间因素来确定何时触发位置更新事件。这意味着,即使您的应用程序在后台运行,也不会持续消耗电池寿命。


1
对我来说是完美的答案。 - benchuk
1
对我没用。有一些东西缺失了。这个答案有效。 - Autonomous
2
请注意,在iOS 11中,您的info.plist必须提供第三个密钥:NSLocationAlwaysAndWhenInUseUsageDescription - Farshid

36
当我遇到这个问题时,原因是线程问题。
确保所有这些方法都在主线程上调用非常重要。 重点是不仅要在主线程上调用startUpdatingLocation方法,还要对其他方法进行相同的处理。
您可以通过将代码包装在内来强制在主线程上运行。
dispatch_sync(dispatch_get_main_queue(), ^{

});

还可以查看这个答案


我和上面的问题一样,但是当我使用你的解决方案后,我的按钮就无法点击了。这很奇怪。 - Dulax
@Tim Bodeit,谢了伙计……你的回答帮了我省了不少事。 - Dharmbir Singh
可能是我没注意到...你在说哪个按钮? - Tim Bodeit
根据我的经验,dispatch_async()已经足够了... 它可能解决界面更新问题 - 只是猜测@dulax - Moose

10

确保你将CLLocationManager添加为属性。

@property (nonatomic , strong) CLLocationManager *locationManager;

1
看起来这个帮了我 - 不然我一直会收到EXC_BAD_ACCESS错误。谢谢 :) - JakeP

6

是的,这个属性对我来说是解决之道,而检查位置服务是否已启用是一个好主意:

if ([CLLocationManager locationServicesEnabled]) {
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [self.locationManager startUpdatingLocation];
}

4
请注意,在 iOS 11 及更高版本中,您需要在 info.plist 中提供第三个密钥:NSLocationAlwaysAndWhenInUseUsageDescription。

4
如果设置了CLLocationManagerDelegate,则MapView Delegate也会被设置。
还要检查模拟器的位置,点击Simulator> Debug> Location, 如果是none,请改为city run或freeway drive。这对我有用。

3
你需要告诉模拟器要模拟哪个位置,如果不指定位置,你的CLLocationManager代理方法将永远不会被调用。你可以在模拟器菜单“Debug -> Location”中进行设置。此外,在Xcode的调试区下方,运行应用程序时会出现一个小的定位箭头。你可以使用它来指定一个GPX文件来模拟移动(但仍然无法与真实设备完全一致)。 https://devforums.apple.com/message/1073267#1073267

0

我的应用程序有时会在我将CLLocationManagerdesiredAccuracy属性更改为kCLLocationAccuracyKilometer后,在第一次调用didUpdateLocations时出现多分钟的延迟:

myLocationManager.desiredAccuracy = kCLLocationAccuracyKilometer; 
[myLocationManager startUpdatingLocation]; // Occasional long delay

将其改回kCLLocationAccuracyBest后,对didUpdateLocations的调用再次立即开始发生:

myLocationManager.desiredAccuracy = kCLLocationAccuracyBest; 
[myLocationManager startUpdatingLocation]; // Calls didUpdateLocations immediately

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