Why isn't locationManager:didUpdateLocations being called? - iphone

Here is some simple code:
// ViewControllerA.m
-(void) viewDidLoad
{
[super viewDidLoad];
self.networkMonitor = [[NetworkMonitor alloc] init];
...
[self.networkMonitor.locationManager startUpdatingLocation];
...
}
in network monitor:
// NetworkMonitor.m
-(id) init
{
self = [super init];
if (self != nil) {
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self];
}
return self;
}
...
// this is never called!
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"%s, location manager returned a new location.", __FUNCTION__);
...
}
// and neither is this
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
NSLog(#"Error: %#", [error description]);
}
I've called startUpdatingLocation, NetworkMonitor implements CLLocationManagerDelegate...why am I not getting any calls to didUpdateLocations? Am I misunderstanding when this method should get called? I assume that once startUpdatingLocation is called, I should receive at least one call to didUpdateLocations... I'm simply trying to get the user's current location (without using a map). Any ideas or thoughts would be much appreciated.

are you building for ios6? from docs: In iOS 5 and earlier, the location manager calls the locationManager:didUpdateToLocation:fromLocation: method instead.

Related

CLLocationManager not returning location after temporarily disabling in settings

I temporarily disabled the location services, and the permissions for my app, so that I could test some code which dealt with the scenario where they're not available. Upon turning them on again, my location now can't be fetched, using this code:
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager startUpdatingLocation];
CLLocation *currentLocation = locationManager.location;
[locationManager stopUpdatingLocation];
The locationManager.location is equal to nil after running this code.
I'm running this on an iPad running iOS 6.
Set the delegate for CLLocationManager
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
Try the delegates of CLLocationManager.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
self.currentLocation = newLocation;
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
// The location "unknown" error simply means the manager is currently unable to get the location.
// We can ignore this error for the scenario of getting a single location fix, because we already have a
// timeout that will stop the location manager to save power.
if ([error code] != kCLErrorLocationUnknown) {
[self stopUpdatingLocation:NSLocalizedString(#"Error", #"Error")];
}
}

Posting current location to rails from iPhone

I am building a rails-backed iphone app that uses AFNetworking to create posts at specific locations. So the post model has lat/lng parameters that should be filled in with the client's current location.
At this point, the posts can be made, but the lat/lng comes up as null.
In my (save:) method I pass a conditional to see if a location was found- this is what is failing i.e. "No Location" is logged.
- (void)save:(id)sender {
[self getLocation];
NSArray *locations;
CLLocation *location = [locations objectAtIndex:0];
Post *post = [[Post alloc] init];
post.content = self.contentTextView.text;
post.photoData = UIImagePNGRepresentation(self.imageView.image);
[self.view endEditing:YES];
ProgressView *progressView = [ProgressView presentInWindow:self.view.window];
if (location) {
[post savePostAtLocation:location withBlock:^(CGFloat progress) {
[progressView setProgress:progress];
} completion:^(BOOL success, NSError *error) {
[progressView dismiss];
if (success) {
[self.navigationController popViewControllerAnimated:YES];
} else {
NSLog(#"ERROR: %#", error);
}
}];
} else {
NSLog(#"No Location");
}
}
I have also attempted to implement a locationManager like so
-(void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
[self getLocation];
}
-(CLLocation *) getLocation{
CLLocationManager * locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
self.locationManager.distanceFilter = 80.0f;
[locationManager startUpdatingLocation];
CLLocation * location = [locationManager location];
return location;
}
I think ideally I would implement the savePostAtlocation in the CLLocationManagerDelegate where I could pass in the locations array like this:
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
CLLocation *location = [locations objectAtIndex:0 /* firstObject */];
if (location) {
[Post createPostAtLocation:location...
But I want to have the post created onSave so I am trying to identify the location but running into some problems..
How do I properly get the current location and pass it into the dictionary?
Any advice on this would be greatly appreciated. Thanks!
Looking at your code, I think you have a slight misunderstanding about how CLLocationManager is designed to work. It looks like you are trying to call [self getLocation] from inside locationManager:didUpdateLocations. This is not correct. Try something like this, inside your save method that is called when you press your button (I would remove the code that's currently in there while testing):
CLLocationManager * locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
self.locationManager.distanceFilter = 80.0f;
[locationManager startUpdatingLocation];
Then it will start generating location data. When that happens, the phone will automatically call locationManager:didUpdateLocations very rapidly. Then, in locationManager:didUpdateLocations you could use:
CLLocation * location = [manager location];
NSLog(#"%#", location);
To see your location data in the console.
What I have written here should get the phone generating location data for you. What you say about createPostAtLocation: in locationManager:didUpdateLocations is probably the correct way to go. When you get the location data, call [manager stopUpdatingLocation] to make the phone stop, then post the location data you got back to your server.

How to make forced update of user location?

I need to get current user location but I don't know if it has changed or not. Can I request a forced location update from CLLocationManager? Or is there any other way to do that?
Stopping and restarting the LocationManager should force the device to re-acquire an initial position.
[locationManager stopUpdatingLocation];
[locationmanager startUpdatingLocation];
I have had the same problem in one of my apps. I actually had to change the app structure.
This is what I have done:
This class has a public method. -(void)locateMe; an abstract class needs to instantiate this class and run the locateMe then when userIsLocated a notification will be broadcasted. and another method can get the result coordinates from (CLLocation *)currentLocation;
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface ManageUserLocation : NSOperation <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
CLLocation *currentLocation;
}
#property (nonatomic, retain) CLLocationManager *locationManager;
#property (nonatomic, retain) CLLocation *currentLocation;
-(void) locateMe;
#end
in the .m
#import "ManageUserLocation.h"
#implementation ManageUserLocation
#synthesize locationManager;
#synthesize currentLocation; // Other classes use this to get the coordination even better you can make another method that even dont get the direct access to currentLocation. It is up to you.
- (id)init
{
self = [super init];
if (self) {
//[self locateMe]; // Just a hook if you need to run it
}
return self;
}
-(void) locateMe {
self.locationManager = nil;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.desiredAccuracy=kCLLocationAccuracyBest;
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// User location has been found/updated, load map data now.
[self.locationManager stopUpdatingLocation];
currentLocation = [newLocation copy];
// WooHoo Tell everyone that you found the userLocation
[[NSNotificationCenter defaultCenter] postNotificationName:#"userLocationIsFound" object:nil];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
// Failed to find the user's location. This error occurs when the user declines the location request or has location servives turned off.
NSString * errorString = #"Unable to determine your current location.";
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Error Locating" message:errorString delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
[errorAlert release];
[locationManager stopUpdatingLocation];
}
- (void)dealloc { #warning dont forget this :) }
#end
Hope this help.
I think is contrary to Apple Guidelines to force updates.
Apple says geo-update will occur automatically, but at un unknown time.

iphone: CLLocation manager delegate method is not called on click of a button

one more bad day god knows whats the problem with this but delegate methods for CLLocation Mangaer are not called once I click a refresh button, on click of this button I ask location manager to update location
-(void) viewWillAppear:(BOOL)animated{
locationManager=[[CLLocationManager alloc] init];
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
locationManager.delegate = self;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(#"failed");
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
NSLog(#"current lat= %f and long=%f ", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
NSDate *eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 10) {
[lat setText:[ NSString stringWithFormat:#"%f", newLocation.coordinate.latitude]];
[lon setText:[ NSString stringWithFormat:#"%f", newLocation.coordinate.longitude]];
}
else {
[lat setText:#"Not changed"];
[lon setText:#"Not changed"];
}
}
-(IBAction) refrechLoc{
NSLog(#"updating location");
[locationManager startUpdatingLocation];
}
Please help me resolve this issue.
Thanks in advance
It seems that it is beginning updating on viewWillAppear, so it won't update the location until it is not stopped by stopUpdatingLocation. If you want to restart updating you should call stopUpdatingLocation before startUpdatingLocation:
-(IBAction) refrechLoc{
NSLog(#"updating location");
[locationManager stopUpdatingLocation];
[locationManager startUpdatingLocation];
}
imho, there is no need in location updating restart in general
You've misunderstood how CLLocationManager works. The delegate is called when CLLocationManager has a new location for you. [locationManager startUpdatingLocation]; merely tells the location manager to start updating the location, so there's no need to call that twice.
EDIT: For clarity: The delegate is called when the location is updated, i.e., when the device has moved.

CLLocation manager keep getting same latitude and longitude when clicking button?

This is my first question in this site.
I have this serious problem.... I'll explain this from the beginning…
in my app i need to get the current location of the user when the user click on the button in the application.. but the problem is when is click on the button its not updating to the current location its getting the previous location. But when i reset the location warnings in the iphone app its get the correct location.
Here is the code steps i did for this application to get the current location of the user...
First I import to the application ...
then i am using global files to keep data of the application because i need to access them through the application.
so what I did in the globle.m and .h file is ...
CLLocationManager* locationManager;
#synthesize locationManager
+ (Globals*)sharedGlobals {
#synchronized(self) {
if(_sharedGlobals == nil) {
_sharedGlobals = [[super allocWithZone:NULL] init];
_sharedGlobals.locationManager = [[CLLocationManager alloc]init];
[_sharedGlobals.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
}
}
return _sharedGlobals;
}
Then in my other view controller I put the CLLocationManagerDelegate and in the .m file
-(IBAction) didTapSearchbtn{
if (![CLLocationManager locationServicesEnabled]) {
}else {
[[Globals sharedGlobals].geoLocations removeAllObjects];
search.text = nil;
[Globals sharedGlobals].fromTextField = NO;
[[Globals sharedGlobals].locationManager setDelegate:self];
[[Globals sharedGlobals].locationManager startUpdatingLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
if (newLocation.horizontalAccuracy < 0) return;
[[Globals sharedGlobals].locationManager setDelegate:nil];
[[Globals sharedGlobals].locationManager stopUpdatingLocation];
[[Globals sharedGlobals].geoLocations setObject:[[NSString alloc] initWithFormat:#"%f", newLocation.coordinate.latitude] forKey:#"geolat"];
[[Globals sharedGlobals].geoLocations setObject:[[NSString alloc] initWithFormat:#"%f", newLocation.coordinate.longitude] forKey:#"geolong"];
[self retriveDataFromInternet];
[[Globals sharedGlobals].locationManager release];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
//GPS error
[[Globals sharedGlobals].locationManager setDelegate:nil];
[[Globals sharedGlobals].locationManager stopUpdatingLocation];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"YumTable!", nil) message:NSLocalizedString(#"Enable Your GPS settings to get your current location", nil) delegate:nil cancelButtonTitle:NSLocalizedString(#"Ok", nil) otherButtonTitles:nil];
[alert show];
[alert release];
[[Globals sharedGlobals].locationManager release];
}
i put the label to my view controller and went different places to take latitudes and longitudes .. but always it getting same latitude and longitude ... but when I reset the location warnings and run the app again it took the correct latitude and longitude ... so if i need to take current location always i have to reset it. But what i need is to get current location every time when i click the search button...
Can any one can say whats wrong in this code and can any one help me ....
And Also very very sorry about my bad english ... :)
The LocationManager will return the previos location because it tries to be as fast as possible and it thinks that this location might be good enough. I usually check the timestamp on the new location to ensure that it is a fresh one. If it is to old I don't stop the manager and wait for the next one.
I would suggest that you look at the sample code provided by Apple, https://developer.apple.com/library/ios/#samplecode/LocateMe/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007801
This code is copied from the example:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// test the age of the location measurement to determine if the measurement is cached
// in most cases you will not want to rely on cached measurements
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0) return;
}
I missed Typed my code ... after I figur that out my application start to work perfectly ... Thank you guys for your great help..
[_sharedGlobals.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
instead of that I used
[_sharedGlobals.locationManager setDesiredAccuracy:kCLLocationAccuracyBestforNavigation];