1

I wrote a wrapper around CLLocationManager class. There are different UIViewControllers using the LocationManager class. It's a singleton and I set it to nil after use. However, it only works with the first class that uses it. How to kill it? I'm already calling stopUpdatingLocation.

I've tried this already

this post suggests that I shouldn't use a singleton, but if I do that, it doesn't work at all.

MyViewController.m

LocationManager * locationManager;

@implementation MyViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    locationManager = [LocationManager sharedManager];
    [locationManager start];
    locationManager.delegate = self;
}

#pragma mark - Delegate functions

-(void)isLocationManagerDelegateTriggered:(CLLocation *) location {
    // works only first time, but gets triggered every time    
    [locationManager stop];
    locationManager.delegate = nil;
    NSLog(@"latitude = %f longitude = %f",location.coordinate.latitude, location.coordinate.longitude);
}

LocationManager.m

#import <CoreLocation/CoreLocation.h>

@implementation LocationManager

CLLocationManager *clLocationManager;

@synthesize delegate;

/* Singleton */
static LocationManager *sharedSingleton;

/* Singleton */
+ (id)sharedManager
{
    static LocationManager *sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
        clLocationManager = [[CLLocationManager alloc] init];
    });
    return sharedMyManager;
}

#pragma mark - Public functions

- (void)start {

    [clLocationManager setDelegate:(id<CLLocationManagerDelegate>)self]; //If I put this         [clLocationManager setDesiredAccuracy:kCLLocationAccuracyBest]; // and this in initialize, it doesn't work anymore.

    [clLocationManager startUpdatingLocation];
}

- (void)stop {
    [clLocationManager stopUpdatingLocation];
}

#pragma mark - CLLocationManagerDelegate

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

        if (currentLocation != nil) {
            [delegate isLocationManagerDelegateTriggered:currentLocation];
        }
}

@end

LocationManager.h

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>

@class LocationManager;

@protocol LocationManagerDelegate

@required
-(void)isLocationManagerDelegateTriggered:(CLLocation *) location;
@end

@interface LocationManager : NSObject <CLLocationManagerDelegate>

+ (id)sharedManager;
-(void)start;
- (void)stop;
- (double) getDistanceToLocationInKM:(CLLocation *) location currentLocation:(CLLocation *)currentlocation;

@property (nonatomic, assign) id  delegate;

@end

The delegate gets fired only once:

2014-05-17 20:04:03.110 Wobbly[2064:60b] latitude = 50.865281 longitude = 5.732814

Community
  • 1
  • 1
Jim Clermonts
  • 1,694
  • 8
  • 39
  • 94
  • What do you consider "not working"? You get a callback for a location change just once, or...? Can you describing in more detail what you are seeing? – quellish May 16 '14 at 17:51

1 Answers1

2

You are allocating the object using:

locationManager = [[LocationManager alloc]init];

It won't create a singleton instance.

Instead of that you need to use like:

I wrote a wrapper around CLLocationManager class. There are different UIViewControllers using the LocationManager class. It's a singleton and I set it to nil after use. However, it only works with the first class that uses it. How to kill it? I'm already calling stopUpdatingLocation.

I've tried this already

this post suggests that I shouldn't use a singleton, but if I do that, it doesn't work at all.

MyViewController.m

LocationManager * locationManager;

@implementation MyViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    locationManager = [LocationManager sharedManager];
    [locationManager start];
    locationManager.delegate = self;
}

#pragma mark - Delegate functions

-(void)isLocationManagerDelegateTriggered:(CLLocation *) location
{
    // works only first time, but gets triggered every time    
    [locationManager stop];
    locationManager.delegate = nil;
}

LocationManager.m

#import <CoreLocation/CoreLocation.h>

@implementation LocationManager

CLLocationManager *clLocationManager;

@synthesize delegate;

/* Singleton */
+ (id)sharedManager
{
    static LocationManager *sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
        clLocationManager = [[CLLocationManager alloc] init];
    });
    return sharedMyManager;
}

#pragma mark - Public functions

- (void)start
{

    [clLocationManager setDelegate:(id<CLLocationManagerDelegate>)self]; //If I put this         [clLocationManager setDesiredAccuracy:kCLLocationAccuracyBest]; // and this in initialize, it doesn't work anymore.

    [clLocationManager startUpdatingLocation];
}

- (void)stop
{
    [clLocationManager stopUpdatingLocation];
}

#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    if(firsttime)
    {
        firsttime = false;
        CLLocation *currentLocation = newLocation;

        if (currentLocation != nil)
        {
            [delegate isLocationManagerDelegateTriggered:currentLocation];
        }
    }
}

@end

LocationManager.h

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>

@class LocationManager;

@protocol LocationManagerDelegate

@required
-(void)isLocationManagerDelegateTriggered:(CLLocation *) location;
@end

@interface LocationManager : NSObject <CLLocationManagerDelegate>

+ (id)sharedManager
- (void)start;
- (void)stop;
- (double) getDistanceToLocationInKM:(CLLocation *) location currentLocation:(CLLocation *)currentlocation;

@property (nonatomic, assign) id  delegate;

@end
Midhun MP
  • 103,496
  • 31
  • 153
  • 200
  • `initialize` is a class method of `NSObject` which is automatically called from the runtime before the class receives the first message. It can be overridden for initialization purposes, but does not return a value. - (That does not necessarily mean that it is a good idea to create the "shared instance" or "singleton" in `initialize`.) – Martin R May 16 '14 at 17:26
  • @MartinR I've updated my question with your answer and it's working now. – Jim Clermonts May 17 '14 at 18:08