Les methods CLLocationManager Delegate ne sont pas appelées

CLLocationManager class CLLocationManager . J'ai une méthode de class simple pour capturer l'location

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

et j'ai les methods de délégué de CLLocationManager aussi

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

maintenant j'essaie d'appeler cette méthode dans mon viewDidLoad comme

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

la méthode est appelée mais les methods déléguées ne sont pas appelées.

J'ai aussi d'autres methods de class et à partir de là si j'essaie d'appeler à nouveau la méthode, la méthode captureLocation est appelée, mais les methods déléguées ne sont pas appelées. Voici la méthode de l'autre class

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

S'il vous plaît aidez-moi à savoir pourquoi les methods de delegates ne sont pas appelés car je suis nouveau dans ce domaine. Merci d'avance.

Sachez également que les permissions CoreLocation ont été modifiées avec iOS 8. Si vous ne requestz pas les nouvelles permissions d'autorisation, CoreLocation ne fait rien. Il échoue silencieusement car les methods déléguées ne sont jamais appelées.

Je me suis rendu count que cette question avait été posée en 2013, mais si vous rencontrez un problème similaire avec les methods de délégué qui ne sont pas appelées, cet article est extrêmement utile:

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

Alors que l'article est très détaillé et long, le correctif de code peut être aussi mineur que ceci:

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

Et vous devez append une valeur à info.plist, qui est le message à afficher dans l'alerte des permissions. Voir capture d'écran.

Capture d'écran d'une nouvelle entrée dans info.plist

Clé: NSLocationWhenInUseUsageDescription

Valeur: L'location est nécessaire pour savoir où vous êtes (Vous pouvez changer cela pour ce que vous voulez)

Vous définissez le delegate du CLLocationManager intérieur d'une méthode de class (c'est-à-dire un préfixe par + plutôt que - ). Ainsi, lorsque vous referencez self dans cette méthode de class, c'est la class, pas une instance de la class. Ainsi, vous essayez de définir le delegate à la class plutôt qu'une instance de la class.

Cela ne marchera pas. Les methods déléguées sont des methods d'instance, pas des methods de class. (C'est probablement pourquoi vous avez dû utiliser la dissortingbution CLLocationManagerDelegate lors de l'affectation du delegate .)

Vous devez réellement instancier la class dans laquelle vous avez implémenté les methods CLLocationManagerDelegate . Si vous ne souhaitez pas lier cette instance à un controller de vue particulier, vous pouvez utiliser un model singleton. Peu importe, vous pouvez définir le délégué du gestionnaire d'location pour qu'il pointe vers cette instance de cette class.


Par exemple, si vous voulez que ce soit un singleton:

 // MyClass.h #import <Foundation/Foundation.h> @interface MyClass : NSObject + (instancetype)sharedManager; - (void)startCapture; - (void)stopCapture; @end 

et

 // 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 

Et alors,

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

L'appel de self dans une méthode + définit votre délégué à zéro car cela signifie ClassName nom de ClassName est ClassName celui de [[ClassName alloc] init] .

tu dois:

mLocationManager.delegate = mLocationManager

au lieu de

 mLocationManager.delegate (id<CLLocationManagerDelegate>)self; 

dans ios6 locationManager:didUpdateToLocation:fromLocation: est déconseillé, vous devez donc append une autre méthode dans votre code …

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

Dans iOS -8 besoin de faire quelques changements:

S'il vous plaît jeter un oeil dans ceci: Obtenir l'location actuel dans iOS-7 et iOS-8