CLLocationManager委托方法未被调用

问题描述 投票:4回答:5

我正在使用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];
}

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

ios ios7 core-location cllocationmanager
5个回答
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添加一个值,这是要在权限警报中显示的消息。看屏幕抓取。

密钥:NSLocationWhenInUseUsageDescription

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


5
投票

你是在一个类方法中设置delegateCLLocationManager(即一个前缀为+而不是-)。所以,当你在该类方法中引用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

然后,

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[MyClass sharedInstance] startCapture];
}

0
投票

在+方法中调用self会将您的委托设置为nil,因为这意味着ClassName[[ClassName alloc] init]一样。

你需要:

mLocationManager.delegate = mLocationManager

代替

mLocationManager.delegate (id<CLLocationManagerDelegate>)self;

0
投票

ios6中,locationManager:didUpdateToLocation:fromLocation:已弃用,因此您需要在代码中添加其他方法...

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

      // this method get called in ios7 . 
}

0
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.