5
votes

Currently, developing an app that needs to get last location from CLLocationManager (without any regular tracking). It doesn't matter how old, accurate it is. I don't need and want to start tracking - I just need to just grab some last location from a cache and that's it. IMHO, CLLocationManager is a shared component in iOS and if some app uses location tracking then another app should be able to use the most recent location from CLLocationManager.location. It should be sufficient just to alloc/init CLLocationManager and grab its location. However it's not. I have tested on iPhone4 - started google maps, saw my current location, then went to my app, but after [[CLLocationManager alloc] init] location property is nil.

UPDATE: tried [locationManager startUpdatingLocation]; and [locationManager stopUpdatingLocation]; but the result is the same. I guess, the only solution is to start regular tracking?

UPDATE2: Strange but there's no alert with "The app wants to use location services" after alloc/init of CLLocationManager. Here's my code fragment:

CLLocationManager *locationManager = [[CLLocationManager alloc] init];

[locationManager startUpdatingLocation];
[locationManager stopUpdatingLocation];
NSLog(@"%@", locationManager.location); //prints nil
2
I recommend you look into How to find your current location with CoreLocation, and store the location found in an NSArray.Aleksander Azizi

2 Answers

2
votes

First you should check if your locationManager has a, let's say, 'static' location pre-saved.

If it does, you're done.

If not, you should startUpdatingLocation and then, in the didUpdateToLocation:fromLocation: callback, stopUpdatingLocation once you get the location.

My experience says that's the best way to get only one location.

UPDATE TO MATCH AUTHOR UPDATES:

You should not stopUpdatingLocation just after startUpdatingLocation. startUpdatingLocation starts a service in background, so you should wait until you get a location, so invoque it in the callback methods.

1
votes

To make any use of CLLocationManager you need to implement CLLocationManagerDelegate somewhere.

-[CLLocationManager startUpdatingLocation] starts an async process. If you stop it in the same runloop cycle the process never gets started and that is the reason you never see the permission dialog.

It goes something like this:

@interface MyClass : NSObject <CLLocationManagerDelegate> {
    CLLocationManager *manager;
    CLLocation *lastLocation;
}

@end

@implementation

- (id)init {
    self = [super init];
    if (self) {
        manager = [[CLLocationManager alloc] init];
        manager.delegate = self;
        [manager startUpdatingLocation];
    }
    return self;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation;
{   
    lastLocation = newLocation;
    [manager stopUpdatingLocation];
}

// in your real implementation be sure to handle the error cases as well.
@end