Separate CLLocationManager for location & heading? - iphone

I have noticed in a few books that quite often two instances of CLLocationManager are created, one for location and a separate one for heading. If you wanted a separate delegate for each I could see the point, but all the methods are unique so I can't really think of a reason for doing this. Is there something I am missing, or is it possible to simplify this and use one CCLocationManager for both location and heading?
// LOCATION
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[customMapView setShowsUserLocation:YES];
// HEADING:
headingManager = [[CLLocationManager alloc] init];
[headingManager setDelegate: self];
[headingManager setHeadingFilter:kCLHeadingFilterNone];
[headingManager startUpdatingHeading];

I've never done this and all my apps have worked absolutely fine - I'd just use the same one for both :)
I can't even begin to think of a reason why you would do this if the delegates were the same!

Related

Why is my userLocation.location always nil?

I have mkmapview delegate to handle authorization events, etc., however, my userLocation is real, but my userLocation.location always returns nil in simulator or on device.
Any pointers on why?
Be sure you have added :
NSLocationWhenInUseUsageDescription in your info.plist project file
Register for CLLocationManagerDelegate
mapView.showsUserLocation=YES;
- (void)viewDidLoad {
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
[locationManager requestWhenInUseAuthorization];
[locationManager startUpdatingLocation];
}
Hope it will help
Test this behavior on your device is Simpler ( or don't forget to set a location in your simulator configuration )

gps stopped when i am calling from the application (automatically stop gps when make phone call hangup)

I have started gps and make phone call using openurl (tel) but when call is hangup it will automatically stopped gps.
actually i want gps on until i reopen app and stop gps by my deactivate button.
hi try this,
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = 1.0f;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
[locationManager startMonitoringSignificantLocationChanges];
i hope this will help you.

Should an app start location tracking in order to get ANY last known location from CLLocationManager?

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
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.
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

CLLocationManager prompt is displaying alert then disappearing

This is one awful bug. When using CLLocationManger, either with startUpdatingLocation or with ALAsset methods to access metadata for a photo, the system is prompting for location access as expected...but the prompt disappears as soon as it's shown. I cannot find the reason for this and am hoping someone else has had this problem. This does not occur with other alerts (such as showing a UIAlertView).
I can even set the purpose property, and it displays, but again, only for a moment then it just closes itself.
This is a big issue for me as I require permission in order to use photo metadata.
Are you creating the CLLocationManager instance in a method like so:
-(void) viewDidAppear:(BOOL)animated {
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
}
If so, then as soon as the function exits, the local locationManager variable is being cleaned up. You should save a reference to the locationManager either on an instance or in a static variable:
static CLLocationManager *locationManager;
-(void) viewDidAppear:(BOOL)animated {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
}
Ugh, now the issue appears to be resolved. And I don't know why or how.

Converted to ARC App crashes on any method iPhone

I converted my app to ARC and removed all the pre-build release errors. It launches, but will crash (EXC_BAD_ACCESS) as soon as I call any method (all of which are attached to UIButtons). I also noticed that it will ask if the user will allow for the app to use the user's location, but the alert will disappear before the user can answer yes or no.
I feel like there's some very basic setting I'm missing causing this.
Here's the first method called, it won't let the user actually say if they'll allow location services. The alert fires then disappears. Does this help anyone's diagnosis?
-(void)startLocation
{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
Also, here's my didFinishLaunchingWithOptions method
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UINavigationController *nav = [[UINavigationController alloc] init];
StartPageViewController *start = [[StartPageViewController alloc]init];
NSManagedObjectContext *context = [self managedObjectContext];
if (!context)
{
// Handle the error.
}
start.managedObjectContext = context;
nav.viewControllers = [NSArray arrayWithObjects:start, nil];
[_window addSubview:[nav view]];
[self.window makeKeyAndVisible];
return YES;
}
Try retaining your navigation controller by making it a strong property on your delegate.
At the moment, I don't see any code that would cause ARC not to release nav at the end of the method. That would release start, which would release context.
All I needed to change (so far) was:
self.window.rootViewController = nav;
instead of:
[_window addSubview:[nav view]];