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

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];

Related

Updating user location using iPhone GPS without internet

I need to get user location and fetch latitude and longitude of even when there is no internet available.
Right now i have implemented CoreLocation methods:-
-(void)updatestart
{
// Current location
_locationManager = [[CLLocationManager alloc]init];
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
_locationManager.delegate = self;
[_locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", error);
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle:#"Error" message:#"Failed to Get Your Location" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation{
[_locationManager stopUpdatingLocation];
NSLog(#"%f",_locationManager.location.coordinate.latitude);
NSLog(#"%f",_locationManager.location.coordinate.longitude);
}
and i am getting the location updates but this only works if we have internet connection.
I guess using iPhone GPS we can fetch the location even without internet.
Any idea of how to implement that??
Thanks in advance.
GPS doesn't need data exchange using internet, but it has basically 2 disadvantages:
it takes a long time to get position if you haven't used it recently (this is
due to satellite search)
it doesn't work inside buildings or where streets are too small
between buildings (this happens a lot in Italy)
Another way that it doesn't need data exchange is location based on cell tower, but of course your device should have cellular chip installed.
From your code I see three things that should be fixed as soon as possible.
Sometimes the first location is cached and it doesn't represent the
actual location
It will be better to stop the location manager when you receive a
valid coordinate, that means: not cached, with an horizontal accuracy >=0 and with an horizontal accuracy that match your requirements,
The delegate methods to get location is deprecated (depending on your
deployment target). Here is a little snippet for the first two
points:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
CLLocation * newLocation = [locations lastObject];
if (newLocation.horizontalAccuracy < 0) {
return;
}
NSTimeInterval interval = [newLocation.timestamp timeIntervalSinceNow];
if (abs(interval)>20) {
return;
}
}

Calculating exact distance in iPhone

I am trying to calculate distance from start using Core Location framework, but when i put the Application on an iPhone device, the data is not correct. Distance keeps on fluctuating and showing random data. Kindly help me out. Also, Altitude is showing zero.
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
//Altitude
if(startingPoint==nil)
self.startingPoint=newLocation;
NSString *currentAltitude = [[NSString alloc] initWithFormat:#"%g",
newLocation.altitude];
heightMesurement.text=currentAltitude;
[currentAltitude release];
//Distance
if(startingPoint==nil)
self.startingPoint=newLocation;
//if(newLocation.horizontalAccuracy <= 100.0f) {
// [locationManager stopUpdatingLocation];
//}
//test start.......................................................
//startlocation
NSString *sp = [[NSString alloc]
initWithFormat:#"%f",startingPoint];
NSLog(#"\nStarting point=%#",startingPoint);
ssp.text=sp;
//endlocation
NSString *ep = [[NSString alloc]
initWithFormat:#"%f",newLocation];
NSLog(#"\nStarting point=%#",newLocation);
eep.text=ep;
//test end............................................................
CLLocationDistance mydistance=[newLocation distanceFromLocation:startingPoint];
NSString *tripString = [[NSString alloc]
initWithFormat:#"%f",mydistance];
distLabel.text=tripString;
[tripString release];
//test........................
[sp release];
[ep release];
}//Location Manager ends..
//Time interval of 3 sec....
-(void)locationUpdate:(NSTimer*)timer{
if(timer != nil) [timer invalidate];
[self.locationManager startUpdatingLocation];
}
As to why your altitude may be zero, please see this answer to a similar question.
This may just be a problem with your NSLog statements, but both the starting and ending points are printed out with NSLog statements that say
NSLog(#"\nStarting point=%#",
The way you seem to have scheduled a 3-second timer is not really the way iOS wants you to use CLLocationManager. The preferred way is to tell CLLocationManager what your location criterion are, and then just start it updating. You don't actually need to keep telling it to start updating every 3 seconds. You can just do it once, and then if you ever decide you don't need any more updates, then call
[locationManager stopUpdatingLocation];
If the OS has no new location information, it probably doesn't make sense to keep asking. It'll tell you when it has new location information, via locationManager:didUpdateToLocation:fromLocation. So, I would recommend starting the process more like this:
CLLocationManager* locationManager = [[CLLocationManager alloc] init];
if ([locationManager locationServicesEnabled]) {
Reachability* netStatus = [Reachability sharedReachability];
if (([netStatus internetConnectionStatus] != NotReachable) || ([netStatus localWiFiConnectionStatus] != NotReachable)) {
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
locationManager.distanceFilter = 100.0; // 100 m, or whatever you want
[locationManager startUpdatingLocation];
} else {
// TODO: error handling
}
}
self.locMgr = locationManager;
[locationManager release];
The location manager will often deliver you multiple results, with increasing accuracy as it hones in on your location. If you're continually restarting it, I'm wondering if that's causing it problems.

iphone gps giving incorrect location

I want to show user's current location with iphone gps feature but problem is it is giving incorrect location .
When i drop pin on map then it drops pin at exact position but when i try to see the location in text then it gives inaccurate location with inaccuracy of 500 to 800 meters approx.I have used reverse geocoding and google api but all giving same location. PLease tell me why this happens and how can i show the exact location of user ?
My code is:
cllocationmanager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyBest; // 100 m
[locationManager startUpdatingLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
CLLocationCoordinate2D here = newLocation.coordinate;
NSLog(#"%f %f ", here.latitude, here.longitude);
MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:here];
[geocoder setDelegate:self];
[geocoder start];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error{
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
NSLog(#"The geocoder has returned: %#", [placemark addressDictionary]);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error" message:[NSString stringWithFormat:#"%#",[placemark addressDictionary]] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
[alertView release];
}
Quick guess: did you check the CLLocation's horizontal accuracy? Quite often the first response I get is very inaccurate, and then subsequent calls get better.
Edit: #pankaj First of all, can you confirm that it is an accuracy issue. If it is the problem that I'm suggesting, then the CLLocation horizontalAccuracy will be large. If not the case then you can ignore my answer and these comments. However, if horizontalAccuracy is a large error then you will have to wait for a better lock. There are two ways to do this:
Wait for a short period of time (a second or two) and see if you get a better lock.
Start requesting location much earlier on, e.g. when the app launches, or when the UIViewController that requires location starts.

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.

didUpdateLocation Method Never Called

I am making one app on iphone sdk4.0.In that did update location method never called.
I have given my code below.Please help.Thanks in advance.
-(id)init
{
[super init];
obj=[[UIApplication sharedApplication]delegate];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
//locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
return self;
}
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(#"%f",newLocation.coordinate.latitude);
NSLog(#"%f",newLocation.coordinate.longitude);
obj=[[UIApplication sharedApplication]delegate];
location=[[CLLocation alloc]initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude];
obj.lattitude1=[NSString stringWithFormat:#"%f",newLocation.coordinate.latitude];
obj.longitude1=[NSString stringWithFormat:#"%f",newLocation.coordinate.longitude];
//location=[[CLLocation alloc]initWithLatitude:39.9883 longitude:-75.262227];
}
Furthermore in iOS8 you must have two extra things:
Add a key to your Info.plist and request authorization from the location manager asking it to start.
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
You need to request authorization for the corresponding location method.
[self.locationManager requestWhenInUseAuthorization]
[self.locationManager requestAlwaysAuthorization]
Code example:
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
Source: http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
HI, your codes seems ok.
now these can be possible reasons :
on your init: try to check if there is locationServicesEnabled or not.
locationManager = [[CLLocationManager alloc] init];
if(locationManager.locationServicesEnabled == NO){
//Your location service is not enabled, Settings>Location Services
}
other reason, you may disallow to get location to your app.
solution: simply remove your application from iPhone and re-build, now it should popup dialog to Allow location.
use this to check error
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
NSLog(#"Error while getting core location : %#",[error localizedFailureReason]);
if ([error code] == kCLErrorDenied) {
//you had denied
}
[manager stopUpdatingLocation];
}
otherwise all seems ok,
you were already running ios 4.0 , which can be install in iPhone 3G and later,
if it was iPhone 2g, then this problem may occur.
Make sure you added CLLocationManager as a property.
#property (nonatomic , strong) CLLocationManager *locationManager;
If you are testing this on the simulator it will not work.
This happens because that method is only called when the device changes location (and the simulator never changes location).
Does -locationManager:didFailWithError: in your delegate ever get called? Maybe you denied access to location data at some point and now don't get prompted, but access is denied.
After you alloc and init your location manager, check to see if location services are allowed. This code is from Apple's "LocateMe" code sample
if (locationManager.locationServicesEnabled == NO) {
UIAlertView *servicesDisabledAlert = [[UIAlertView alloc] initWithTitle:#"Location Services Disabled" message:#"You currently have all location services for this device disabled. If you proceed, you will be asked to confirm whether location services should be reenabled." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[servicesDisabledAlert show];
[servicesDisabledAlert release];
}
If you're testing with the simulator, try testing with a device instead. The simulator requires that the computer's WiFi is turned on, and that it can locate a WiFi base station that's in it's database of known locations.