1

I sourced my locationManager out in a own class and file

Now I want to be notified when the location is updated. So I tried to implement the delegation pattern. But for some reason it does not work. What I did:

  • In Location.h: specified class, protocol, ivar and property id, delegation method
  • In Location.m: added a call to the delegation method
  • In ViewController.h: added delegation protocol
  • In ViewController.m: implemented the delegation method

Build and run the code. But the delegation method in ViewController.m is not called :( Any ideas what i missed?

Output

2013-07-04 11:55:30.429 Sandbox2[2001:c07] Inside Lokation::getLocation
2013-07-04 11:55:30.443 Sandbox2[2001:c07] Inside Lokation::locationManager
2013-07-04 11:55:30.449 Sandbox2[2001:c07] currentLat: 51.509980 currentLng -0.133700
// Missing NSLog Statement of the delegate method didFindLocation...

ViewController.h

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
// added Lokation header
#import "Lokation.h"

// added LokationDelegate
@interface ViewController : UIViewController <CLLocationManagerDelegate, LokationDelegate>

@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()
@property (strong, nonatomic) Lokation *lokation; 
@end

@implementation ViewController


- (void)viewDidLoad
{
    [super viewDidLoad];

    //[self getLocation];
    self.lokation = [[Lokation alloc] init];
    self.lokation.delegate = self;
    [self.lokation getLocation];
}

// added delegate function of Lokation
// Should be run after the locationmanager found a location
-(void)didFindLocation {
    NSLog(@"I am found a lokation and I am now in the ViewController");
}

Lokation.h (20130704 updated to working code)

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

// Added class, protocol and method for the delegate
@class Lokation;
@protocol LokationDelegate <NSObject>

-(void)didFindLocation;

@end

@interface Lokation : NSObject <CLLocationManagerDelegate> {
    CLLocationDegrees currentLat;
    CLLocationDegrees currentLng;
}

@property (strong, nonatomic) CLLocationManager *locationManager;
@property (nonatomic, strong) CLLocation *currentLoc;
// added delegate property
@property (assign, nonatomic) id<LokationDelegate> delegate; 

-(void)getLocation; 

@end

Lokation.m (20130704 updated to working code)

#import "Lokation.h"

@implementation Lokation

@synthesize locationManager = _locationManager;
@synthesize currentLoc = _currentLoc;

-(void)getLocation {
    NSLog(@"Inside Lokation::getLocation");
    // active location determination
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
    // We don't want to be notified of small changes in location,
    // preferring to use our last cached results, if any.
    self.locationManager.distanceFilter = 50;
    [self.locationManager startUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
    NSLog(@"Inside Lokation::locationManager");

    if (!oldLocation ||
        (oldLocation.coordinate.latitude != newLocation.coordinate.latitude &&
         oldLocation.coordinate.longitude != newLocation.coordinate.longitude)) {

            currentLat = newLocation.coordinate.latitude;
            currentLng = newLocation.coordinate.longitude;   
        } else { // oldLocation
            currentLat = oldLocation.coordinate.latitude;
            currentLng = oldLocation.coordinate.longitude;
        }

    self.currentLoc = [[CLLocation alloc] initWithLatitude:currentLat longitude:currentLng];
    NSLog(@"currentLat: %f currentLng %f", currentLat, currentLng);

    // added call to the delegate function
    [self.delegate performSelector:@selector(didFindLocation)];
}

- (void)locationManager:(CLLocationManager *)manager
       didFailWithError:(NSError *)error {
    NSLog(@"%@", error);
}
Community
  • 1
  • 1
jerik
  • 5,714
  • 8
  • 41
  • 80
  • 1
    Try `[self.delegate performSelector:@selector(didFindLocation)];`? Also `NSLog` the value of `delegate` to check if it is `nil`. Additionally when you declare `@property` no need to explicitly create an `ivar`. It will be automatically created for you. – Amar Jul 04 '13 at 10:33

1 Answers1

0

Hmm..i think you are doing right but if i do change like below:

remove __unsafe_unretained id<LokationDelegate> delegate; and replace @property (assign, nonatomic) id<LokationDelegate> delegate with @property (retain) id<LokationDelegate> delegate (and synthesize property),it works like charm for me

iSpark
  • 952
  • 7
  • 18
  • did that. `@property (assign, nonatomic) id delegate` works fine. Snythesize properties not needed anymore in xcode 4.6.2 at least. Which advantage would I have with `@property (retain) ...` ? – jerik Jul 05 '13 at 07:31
  • @MuraliK Retaining a delegate is a bad idea as it will cause [retain cycles](http://stackoverflow.com/questions/918698/why-are-objective-c-delegates-usually-given-the-property-assign-instead-of-retai) in your code leading to memory leaks. – Amar Jul 08 '13 at 06:05