singleton pour la mise à jour de plusieurs vues

Je veux mettre à jour l'location d'user dans toutes les vues, après que le button locateButton dans la barre de navigation est pressé dans n'importe quelle vue. J'ai commencé en créant un singleton.

Location.h

#import <Foundation/Foundation.h> #import <CoreLocation/CoreLocation.h> #import <MapKit/MapKit.h> @interface Location : NSObject <CLLocationManagerDelegate> @property (nonatomic, strong) CLLocationManager* locationManager; + (Location*)sharedSingleton; @end 

Location.m

 #import "Location.h" @implementation Location { CLLocationManager *locationManager; CLGeocoder *geocoder; CLPlacemark *placemark; } @synthesize locationManager; - (id)init { self = [super init]; if(self) { self.locationManager = [CLLocationManager new]; [self.locationManager setDelegate:self]; [self.locationManager setDistanceFilter:kCLDistanceFilterNone]; [self.locationManager setHeadingFilter:kCLHeadingFilterNone]; [self.locationManager startUpdatingLocation]; self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; //do any more customization to your location manager } return self; } + (Location*)sharedSingleton { static Location* sharedSingleton; if(!sharedSingleton) { @synchronized(sharedSingleton) { sharedSingleton = [Location new]; } } return sharedSingleton; } #pragma mark - CLLocationManagerDelegate - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog(@"didFailWithError: %@", error); UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [errorAlert show]; } - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { NSLog(@"didUpdateToLocation: %@", newLocation); CLLocation *currentLocation = newLocation; if (currentLocation != nil) { latLabel.text = [NSSsortingng ssortingngWithFormat:@"%.8f", currentLocation.coordinate.longitude]; longLabel.text = [NSSsortingng ssortingngWithFormat:@"%.8f", currentLocation.coordinate.latitude]; } // Stop Location Manager [locationManager stopUpdatingLocation]; // Reverse Geocoding NSLog(@"Resolving the Address"); [geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) { NSLog(@"Found placemarks: %@, error: %@", placemarks, error); if (error == nil && [placemarks count] > 0) { placemark = [placemarks lastObject]; addressLabel.text = [NSSsortingng ssortingngWithFormat:@"%@, %@", placemark.locality, placemark.administrativeArea]; addressLabel.numberOfLines = 0; } else { NSLog(@"%@", error.debugDescription); } } ]; } @end 

Je veux utiliser ceci pour mettre à jour l'user lat et long sur chaque vue quand le button de localization dans la barre de navigation supérieure est pressé dans la vue courante.

 - (IBAction)locationPressed:(id)sender { [[Location sharedSingleton].locationManager startUpdatingLocation]; } 

NSNotifications serait-il le meilleur? Si oui, comment les implémenter dans Location.m et les controllers de vue? Merci.

Ce que je ferais serait d'utiliser le model d'observateur. Dans votre singleton, conservez un NSMutableArray de tous les observateurs.

 NSMutableArray *observers; 

Vous aurez besoin d'un protocole auquel tous les observateurs se conformeront:

 @protocol LocationObserver <NSObject> - (void)locationDidChange:(CLLocation *)updatedLocation; @end 

puis quand l'location change juste faire cela

 for (id<LocationObserver> observer in observers) { [observer locationDidChange:newLocation]; } 

Vous devez également avoir une méthode addObserver et removeObserver qui prend un id<LocationObserver> et l'ajoute / supprime du tableau.

Voici ce que j'ai fait et vous pouvez find l'exemple complet sur github https://github.com/irfanlone/CLLocationManager-Singleton-Swift

Importez simplement ce file dans votre projet, puis vous pouvez choisir d'implémenter le composant LocationUpdateProtocol ou écouter les notifications pour les mises à jour d'location.

 import MapKit protocol LocationUpdateProtocol { func locationDidUpdateToLocation(location : CLLocation) } /// Notification on update of location. UserInfo contains CLLocation for key "location" let kLocationDidChangeNotification = "LocationDidChangeNotification" class UserLocationManager: NSObject, CLLocationManagerDelegate { static let SharedManager = UserLocationManager() private var locationManager = CLLocationManager() var currentLocation : CLLocation? var delegate : LocationUpdateProtocol! private override init () { super.init() self.locationManager.delegate = self self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.distanceFilter = kCLLocationAccuracyHundredMeters locationManager.requestAlwaysAuthorization() self.locationManager.startUpdatingLocation() } // MARK: - CLLocationManagerDelegate func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation) { currentLocation = newLocation let userInfo : NSDictionary = ["location" : currentLocation!] dispatch_async(dispatch_get_main_queue()) { () -> Void in self.delegate.locationDidUpdateToLocation(self.currentLocation!) NSNotificationCenter.defaultCenter().postNotificationName(kLocationDidChangeNotification, object: self, userInfo: userInfo as [NSObject : AnyObject]) } } } 

Usage:

 class ViewController: UIViewController, LocationUpdateProtocol { var currentLocation : CLLocation! override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: "locationUpdateNotification:", name: kLocationDidChangeNotification, object: nil) let LocationMgr = UserLocationManager.SharedManager LocationMgr.delegate = self } // MARK: - Notifications func locationUpdateNotification(notification: NSNotification) { let userinfo = notification.userInfo self.currentLocation = userinfo!["location"] as! CLLocation print("Latitude : \(self.currentLocation.coordinate.latitude)") print("Longitude : \(self.currentLocation.coordinate.longitude)") } // MARK: - LocationUpdateProtocol func locationDidUpdateToLocation(location: CLLocation) { currentLocation = location print("Latitude : \(self.currentLocation.coordinate.latitude)") print("Longitude : \(self.currentLocation.coordinate.longitude)") } }