3

Je suis assez nouveau sur le développement iOS (ma première application) et j'ai fait face à ce problème.Personnalisation de la classe Location Manager à l'aide de CLLocationManager

J'ai une application iPhone qui devrait obtenir l'emplacement actuel de l'utilisateur dans plusieurs ViewControllers lorsque le bouton de l'utilisateur touche. Pour éviter le code redondant (mise en œuvre locationManager:didFailWithError, locationManager:didUpdateToLocation:fromLocation, etc. plusieurs fois dans différents contrôleurs de vue) j'ai décidé de créer une classe personnalisée appelée LocationManager:

LocationManager.h

@interface LocationManager : NSObject <CLLocationManagerDelegate> { 
@private 
    CLLocationManager *CLLocationManagerInstance; 
    id<LocationManagerAssigneeProtocol> assignee; 
} 

-(void) getUserLocationWithDelegate:(id) delegate; 

LocationManager.m J'ai un protocole appelé LocationManagerAssigneeProtocol que mes ViewControllers mettre en œuvre

@protocol LocationManagerAssigneeProtocol <NSObject> 

@required 
-(void) didUpdateToLocation:(CLLocation *) location; 

@end 

et dans mon viewcontroller si nécessaire

- (IBAction)getMyLocation:(id)sender { 

    [locationMgr getUserLocationWithDelegate:self]; 
} 

Ce code fonctionne parfaitement, cependant, j'ai le sentiment que je ne respecte pas certains modèles de conception ici en laissant LocationManager être capable d'appeler une fonction de la classe qui a elle-même lancé un appel à Location Manager. D'un autre côté, je ne veux pas aller de l'avant avec CLLocationManagerDelegate pour tous mes viewcontrollers qui sont censés fonctionner avec des emplacements.

Y a-t-il une meilleure solution à ce problème?

+0

Je ne suis pas sûr que je suis votre souci de "laisser LocationManager être en mesure d'appeler une fonction de la classe qui a elle-même lancé un appel". Vous utilisez un protocole délégué pour le faire si je ne me trompe pas, ce qui est souhaitable. –

+0

Je pense que c'est bien, c'est comme ça que la délégation fonctionne, vous n'avez pas de dépendance sur la classe mais seulement sur le protocole. La seule chose que je suggère est que peut-être vous voudrez peut-être passer à un système basé sur la notification si vous avez plusieurs contrôleurs de vue en fonction de la même instance pour les mises à jour de localisation. –

+0

@CarlVeazey Pourriez-vous apporter un exemple de ce que vous changeriez pour le rendre basé sur la notification? –

Répondre

2

Je suis d'accord avec @CarlVeazey sur celui-ci. Les délégués sont parfaits pour une relation 1 à 1 existant à un moment donné, mais dans votre cas, il semble que vous ayez besoin de plusieurs viewControllers pour répondre aux événements de localisation à un moment donné. Il suffit donc de supprimer tout ce qui concerne votre délégué et son protocole associé.

je serais probablement faire classe LocationManager un singleton et de modifier les méthodes de mise à jour:

+(LocationManager *)sharedInstance 
{ 
    static LocationManager *_sharedInstance = nil; 
    static dispatch_once_t oncePredicate; 
    dispatch_once(&oncePredicate, ^{ 
     _sharedInstance = [[self alloc] init]; 
    }); 

    return _sharedInstance; 
} 

-(void)getUserLocation 
{ 
    if ([CLLocationManager locationServicesEnabled]) 
     [CLLocationManager startUpdatingLocation]; 
} 

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 
{ 
    [CLLocationManagerInstance stopUpdatingLocation]; 
    [[NSNotificationCenter defaultCenter] postNotificationWithName:@"LocationManagerDidUpdateLocation" object:newLocation]; 
} 

... Puis tout viewController qui a besoin d'utiliser cette classe aurait quelque chose comme:

-(void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [[NSNotificationCenter defaultCenter] addObserverForName:@"LocationManagerDidUpdateLocation" object:self queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { 
     CLLocation *location = note.object; 
     ... 
    }]; 
} 

-(IBAction)getMyLocation:(id)sender { 
    [[LocationManager sharedInstance] getUserLocation]; 
} 

Espérons que cela aide et a du sens.

Questions connexes