【问题标题】:CLLocationManager startUpdatingLocation not calling locationManager:didUpdateLocations: or locationManager:didFailWithError:CLLocationManager startUpdatingLocation 未调用 locationManager:didUpdateLocations: 或 locationManager:didFailWithError:
【发布时间】:2014-11-13 00:58:17
【问题描述】:

我正在尝试在我的 iOS 项目中使用 CLLocationManager 框架来访问用户的位置,但是当我调用时

[locationManager startUpdatingLocation]

locationManager:didUpdateLocations:locationManager:didFailWithError: 都没有被调用。

//myViewController.h
@interface myViewController : UITableViewController <CLLocationManagerDelegate>
@end

//myViewController.m
@implementation myViewController{
    CLLocationManager *locationManager;
}

//edit
- (void)viewDidLoad
{
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
}
//finish edit

-(void)getLocation
{
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [locationManager startUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)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 didUpdateLocations:(NSArray *)locations
{
    CLLocation *newLocation = locations[[locations count] -1];
    CLLocation *currentLocation = newLocation;
    NSString *longitude = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
    NSString *latitude = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];

if (currentLocation != nil) {
   NSLog(@"latitude: %@", latitude);
   NSLog(@"longitude: @"%@", longitude);
}else {
    UIAlertView *errorAlert = [[UIAlertView alloc]
                               initWithTitle:@"Error" message:@"Failed to Get Your Location" 
                                                     delegate:nil 
                                            cancelButtonTitle:@"OK" 
                                            otherButtonTitles:nil];
    [errorAlert show];
}

}
@end

尽管文档中说了什么,但都没有调用委托方法:

“此方法立即返回。调用此方法会导致位置管理器获取初始位置修复(可能需要几秒钟)并通过调用其 locationManager:didUpdateLocations: 方法通知您的委托 [...] 除了您的委托对象实现了locationManager:didUpdateLocations: 方法,它也应该实现locationManager:didFailWithError: 方法来响应潜在的错误。”

不知道如何调试问题。

谢谢,

JA

【问题讨论】:

  • getLocation 被调用了吗?您是否在寻找 locationServicesEnabled 退货或 authorizationStatus 退货?
  • 是的,get location 被调用。不完全确定locationServicesEnabled 是什么意思。 locationManager:didChangeAuthorizationStatus 应该返回什么?
  • 您是否初始化了位置管理器。 [[CLLocationManager alloc] 初始化]
  • 是的,viewDidLoad 对不起,我忘了包括那个
  • 你在用模拟器吗?如果是这样,这在 StackOverflow 上被问了太多次了

标签: ios objective-c cllocationmanager


【解决方案1】:

因此,如果您在模拟器中运行,请不要忘记在模拟器菜单中设置位置。看起来如果它设置为 none,则委托中不会调用任何内容...我不确定这是否也可以在真实设备上发生,但可能是模拟器特定的。

【讨论】:

    【解决方案2】:

    我的代码库中有以下内容:

    -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
        if( status == kCLAuthorizationStatusAuthorizedAlways ) {
            _locationManager = [[CLLocationManager alloc] init];
            _locationManager.delegate = self;
            _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
            _locationManager.distanceFilter = 200;
        }
    }
    

    原来这是在无限循环中调用的,因为初始化 locationManager 会出于某种原因触发此方法?我没有意识到这一点。当授予权限时,我把它放在那里。相反,我设置了一个位置管理器并开始更新位置,但随后它被触发并将其替换为一个不更新位置的管理器,并且不断循环。

    对我来说,解决方案就是将&amp;&amp; !_locationManager 添加到 if 条件中。

    【讨论】:

      【解决方案3】:

      您需要在项目中添加以下内容,

      1. 在项目的 plist 中添加以下内容:

        1. Key: NSLocationAlwaysUsageDescription Type:String
        2. Key: NSLocationWhenInUseUsageDescription Type:String
      2. 在带有[locationManager startUpdatingLocation] 的.m 文件中添加此条件:

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

      那么只有你的 CLLocationManager 委托方法会被调用。

      【讨论】:

        【解决方案4】:

        您强烈需要检查您是否在主线程上初始化了 CLLocationManager。 在其他情况下,您将不会收到 updateLocation 事件。

        我在 Apple 文档中找不到此类信息,但它对我有用。

        【讨论】:

        • 非常感谢,这是我的问题!还要注意,对我来说,我会使用模拟器接收 updateLocation 事件,但不会在设备上接收......也许是因为架构差异。干杯!
        • 位置管理器需要运行循环。只要该线程具有运行循环,您就可以进入后台线程。所以对于后台线程,你需要自己创建运行循环。
        • 难以置信!刚刚花了几个小时弄清楚为什么 locationmanager 没有触发事件(在 macOS 上),但我做的一切都是正确的,我只是不在 ui 线程上。感谢您提供此信息。
        【解决方案5】:

        只需将这个添加到 info.plist 中

        NSLocationAlwaysUsageDescription --- 我需要位置

        NSLocationWhenInUseUsageDescription --- 我需要位置

        隐私 - 位置使用说明 --- 我需要位置

          locationManager = [[CLLocationManager alloc] init];
          locationManager.delegate=self;
          locationManager.desiredAccuracy=kCLLocationAccuracyBest;
          locationManager.distanceFilter=kCLDistanceFilterNone;
          [locationManager requestWhenInUseAuthorization];
          [locationManager startMonitoringSignificantLocationChanges];
          [locationManager startUpdatingLocation];
        

        现在它肯定会调用你的 didUpdateToLocation。

        更多详情click here

        【讨论】:

        • 请注意,应更改“我需要位置”以描述您实际应用的设计用途。它在授权消息中传达给最终用户。
        • 使用标准位置更新开始重要监控是否正常?还是你应该选择两者之一?
        • 完美运行!谢谢。
        • 在看到你的答案之前一直在努力解决这个问题。这个:NSLocationWhenInUseUsageDescription ---我需要位置救了我。谢谢大佬
        • @Mohit tomar,你好先生方法尚未在我的应用程序中调用,我已经在我的 plist 文件中添加了密钥
        【解决方案6】:

        从 iOS 8 开始,位置服务的工作方式略有不同。

        主要是你需要在你的Info.plist文件中添加一个keyNSLocationWhenInUseUsageDescription,并添加一个说明为什么你的应用需要Location,比如“Location required to ...”。

        请注意,您可能还需要检查 iOS 版本。只有 iOS 8 及更高版本的位置管理器可以监听 requestWhenInUseAuthorization 呼叫。

        下面的链接显示了更多详细信息: http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/

        祝你好运!

        【讨论】:

        • 太棒了!...您在上面描述的链接“nevan.net/2014/09/core-location-manager-changes-in-ios-8”真的很有帮助
        • 链接很有帮助。
        • 太棒了...非常有用的链接:D 谢谢。
        • NSLocationWhenInUseUsageDescription 是关键,我浪费了 2 个小时来寻找这个小旋钮,您放入其中的字符串将作为您需要访问当前位置的原因呈现给最终用户。
        【解决方案7】:

        我认为您应该检查此链接。声明时您没有保留位置管理器对象。

        请给你对象的财产 @property(非原子,强)

        Why the CLLocationManager delegate is not getting called in iPhone SDK 4.0?

        【讨论】:

          【解决方案8】:

          在 iOS 8.0 中,您需要先调用 -[CLLocationManager requestWhenInUseAuthorization ]-[CLLocationManager requestAlwaysAuthorization],以便要求用户授予您的应用使用该位置的权限。

          【讨论】:

          • 我添加了行 [locationManager requestWhenInUseAuthorization];在 getLocation 方法的开头,但它仍然没有提示我...
          • 转到您手机的设置->隐私->定位服务并确保它处于开启状态,然后查看您的应用有哪些选项。如果在某个时候被拒绝,应用程序将永远不会再次提示。
          • 试试这个[CLLocationManager authorizationStatus]
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-07-26
          • 1970-01-01
          • 1970-01-01
          • 2016-05-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多