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]; } 

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

也知道CoreLocation的权限已经改变了iOS 8.如果你没有请求新的权限授权,CoreLocation不会做任何事情。 它悄然失败,因为委托方法从来没有被调用。

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

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

虽然这篇文章非常详细而且很长,但实际的代码修复可以像这样简单:

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

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

在info.plist中抓取新条目

键:NSLocationWhenInUseUsageDescription

价值:位置是需要找出你在哪里(你可以改变它为任何你想要的)

你正在设置CLLocationManagerdelegate在一个类的方法(即前缀+而不是- )。 所以,当你在这个类方法中引用self时候,那就是类,而不是类的一个实例。 所以,你正试图把delegate设置到类而不是类的一个实例。

这是行不通的。 委托方法是实例方法,而不是类方法。 (这大概是为什么你必须在分配delegate时使用CLLocationManagerDelegate 。)

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


例如,如果你想要它是一个单身人士:

 // 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]; } 

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

你需要:

mLocationManager.delegate = mLocationManager

代替

 mLocationManager.delegate (id<CLLocationManagerDelegate>)self; 

ios6 locationManager:didUpdateToLocation:fromLocation:已被弃用,所以你需要在你的代码中添加另一种方法…

 -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { // this method get called in ios7 . } 

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

请看看这个: 获取iOS-7和iOS-8的当前位置