CLLocationManager委托方法未被调用

时间:2013-11-19 12:59:48

标签: ios ios7 core-location cllocationmanager

我正在使用CLLocationManager课程。我有一个简单的类方法来捕获位置

+(void)captureLocation{
    mLocationManager = [[CLLocationManager alloc]init];
    mLocationManager.delegate = (id<CLLocationManagerDelegate>)self;
    mLocationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [mLocationManager startUpdatingLocation];
}

我有CLLocationManager的委托方法

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation   *)newLocation fromLocation:(CLLocation *)oldLocation
{
}

现在我想在viewDidLoad中将此方法称为

- (void)viewDidLoad
{
    [super viewDidLoad];
    [myclass captureLocation];
}

调用该方法但未调用委托方法。

我还有其他类方法,如果我再次尝试调用该方法,则会调用captureLocation方法,但不会调用委托方法。这是另一个类方法

+(void)initialize{
    [self captureLocation];
}

请帮助我找出为什么委托方法没有被调用,因为我是这个领域的新手。提前谢谢。

5 个答案:

答案 0 :(得分:10)

另请注意,iOS 8的CoreLocation权限已更改。如果您未请求新的权限授权,则CoreLocation不会执行任何操作。它安静地失败,因为从不调用委托方法。

我意识到这个问题是在2013年被问到的,但是如果你遇到类似的问题而没有调用委托方法,那么这篇文章非常有帮助:

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

虽然文章非常详细且篇幅很长,但实际的代码修复可能与此相同:

if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
    [locationManager requestWhenInUseAuthorization];
}

您必须向info.plist添加一个值,这是要在权限警报中显示的消息。看屏幕抓取。

Screen grab of new entry in info.plist

密钥:NSLocationWhenInUseUsageDescription

价值:需要位置才能找到你所在的位置(你可以根据需要改变它)

答案 1 :(得分:5)

您要在类方法中设置delegate的{​​{1}}(即一个前缀为CLLocationManager而不是+)。因此,当您在该类方法中引用-时,这就是类,而不是类的实例。因此,您试图将self设置为类而不是类的实例。

那不行。委托方法是实例方法,而不是类方法。 (这可能是您在分配delegate时必须使用CLLocationManagerDelegate强制转换的原因。)

您必须实际实例化您已实施delegate方法的任何类。如果您不想将该实例绑定到特定视图控制器,则可以使用单例模式。无论如何,您可以将位置管理器的委托设置为指向该类的实例。


例如,如果您希望它是单身人士:

CLLocationManagerDelegate

//  MyClass.h

#import <Foundation/Foundation.h>

@interface MyClass : NSObject

+ (instancetype)sharedManager;
- (void)startCapture;
- (void)stopCapture;

@end

然后,

//  MyClass.m

#import "MyClass.h"
#import <CoreLocation/CoreLocation.h>

@interface MyClass () <CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager *locationManager;

@end

@implementation MyClass

+ (instancetype)sharedManager
{
    static id sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
    });
    return sharedMyManager;
}

- (void)startCapture
{
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [self.locationManager startUpdatingLocation];
}

- (void)stopCapture
{
    [self.locationManager stopUpdatingLocation];
    self.locationManager = nil;
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    // ...
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    // ...
}

@end

答案 2 :(得分:0)

在+方法中调用self会将您的委托设置为nil,因为它与ClassName中的[[ClassName alloc] init]相同。

你需要:

mLocationManager.delegate = mLocationManager

而不是

mLocationManager.delegate (id<CLLocationManagerDelegate>)self;

答案 3 :(得分:0)

不推荐使用ios6 locationManager:didUpdateToLocation:fromLocation:中的

,因此您需要在代码中添加其他方法...

-(void)locationManager:(CLLocationManager *)manager
   didUpdateToLocation:(CLLocation *)newLocation
          fromLocation:(CLLocation *)oldLocation
{

      // this method get called in ios7 . 
}

答案 4 :(得分:0)

在iOS -8中需要做一些更改:

请看一下:Get current location in iOS-7 and iOS-8