In Xcode 4.5 apple introduced apple new maps. My application heavliy requires map services. And I have noticed in my application it shows the wrong current location until you delete the app and reopen it shows the right current location (Sometimes it doesn't). Just to mention I was connected to 4G when it show the wrong current location. Is there a way to fix this bug because my application heavily needs the right location. Thanks in advance. If you could provide code it would help a lot...Edit: Same Issue in Apple Map App
My Code:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
{
}
if (!oldLocation)
totalDistance = 0.0;
else
totalDistance += [newLocation distanceFromLocation:oldLocation];
}
The old approach from apple docs seems still working in iOS6 (didn't notice this in my active app (it tracks user's route via gps))
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0) return;
if (newLocation.horizontalAccuracy < 0) return;
// proceed with coords here
}
UPDATE from the discussion:
Calculating total and current distance could be done like this (excluding some minor stuff):
// somewhere at the top
CLLocation* lastUsedLocation = nil; // last location used in calculation
CLLocation* pointA = nil; // start of the track
double totalDistance = 0; // total distance of track
double currentDistance = 0; // distance between startTrack point and current location
...
// when you start updating location:
- (void) startTracking {
lastUsedLocation = nil;
pointA = nil;
totalDistance = 0;
currentDistance = 0;
[locationManager startUpdatingLocation];
}
...
// location update callback
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0) return; // filter cached
if (newLocation.horizontalAccuracy < 0) return; // filter invalid
if(!pointA) pointA = [newLocation retain];
if(lastUsedLocation)
{
totalDistance += [newLocation distanceFromLocation:lastUsedLocation];
}
currentDistance = [pointA distanceFromLocation:newLocation];
[lastUsedLocation release];
lastUsedLocation = [newLocation retain];
}
If you need the option to turn off background location on purpose you disable it manually like:
- (void)applicationDidEnterBackground:(UIApplication *)application {
if(backgroundLocationDisabled)
{
[locationManager stopUpdatingLocation];
// additional stuff
}
}
you should check the timestamp .. if i understand your app logic correctly, you could do something like -
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSDate* time = newLocation.timestamp;
NSTimeInterval timePeriod = [time timeIntervalSinceNow];
if(timePeriod < SOME_MINIMUM_TIME_PERIOD ) { //for eg: timePeriod < 1.0
totalDistance += [newLocation distanceFromLocation:oldLocation];
} else {
// skip.. or do what you do on a 'location-not-updated' event
}
}
I have noticed the same problem with Xcode 4.4+. The problem only occurs (randomly, or so it seems) within Xcode: if you upload the app to the App Store, this is not a problem anymore. In the meantime, please file a bug.
Related
I am having an issue with sending location to other users. I using Parse.com as my backend and I use this code to get a location:
-(void)sendLocation{
if ([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]){
[locationManager requestWhenInUseAuthorization];
}
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
[locationManager stopUpdatingLocation]; //kill it NOW or we have duplicates
if(!self.haveLocation) {
self.haveLocation=YES;
NSLog(#"didUpdateToLocation: %#", newLocation);
self.currentLocation = newLocation;
self.currentLocationGeoPoint= [PFGeoPoint geoPointWithLocation:self.currentLocation];
}
If I send myself a message from my current location and then open the message to view it, by comparing the current location circle with the pin dropped I can see they aren't in the same place and a fair distance apart.
I have the BOOL var haveLocation to make sure it is only refreshed once. Do I need to refresh it more times or something? Any pointers on how to make this more accurate would be really appreciated! Thanks
I tried following the apple example LocateMe:
I now have:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0) return;
// test that the horizontal accuracy does not indicate an invalid measurement
if (newLocation.horizontalAccuracy < 0) return;
// test the measurement to see if it is more accurate than the previous measurement
if (self.bestEffortAtLocation == nil || self.bestEffortAtLocation.horizontalAccuracy > newLocation.horizontalAccuracy) {
// store the location as the "best effort"
self.bestEffortAtLocation = newLocation;
if (newLocation.horizontalAccuracy <= locationManager.desiredAccuracy) {
[locationManager stopUpdatingLocation];
//this code after getting the location
NSLog(#"didUpdateToLocation: %#", newLocation);
}
}
}
However when I tap send location it just runs forever and doesn't stop updating.. I have locationManager.desiredAccuracy = kCLLocationAccuracyBest; set too.
The location manager may send you several updates as it improves its accuracy. This is a feature designed to give you information it as as quickly as possible, while eventually getting the best information to you (at least up to the accuracy you requested). You are actively avoiding those updates, so you are likely getting the least accurate information.
You should check the horizontalAccuracy to determine if it is accurate enough for your use.
Note that you cannot compare horizontalAccuracy to kCLLocationAccuracyBest. "Best" is a constant -1. You need to compare it to what you need (in meters), and probably set a timeout to give up if it takes too long to get there (the system may not be able to provide you an arbitrarily accurate value.)
I want to get the current location latitude and longitude without using the map, is it possible to get like that, I am not getting that from searching the internet, can any one help me to find that.
I tried this with using the core location but even I am not got any thing.
please tell me how to find the latitude and longitude, thank you.
//remember to stop before you are done, either here or in view disappearance.
- (void) dealloc
{ [locationManager stopUpdatingLocation]; }
in .h file:
CLLocationManager *locationMgr;
in .m file:on load
locationMgr =[[CLLocationManager alloc] init];
locationMgr.desiredAccuracy = kCLLocationAccuracyBest;
locationMgr.delegate = self;
if ([locationMgr respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[locationMgr requestWhenInUseAuthorization];
}
[locationMgr startUpdatingLocation];
add following delegates:
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
// Handle location updates
CLLocationCoordinate2D location=newLocation.coordinate;
float altitude = newLocation.altitude;
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
// Handle error
NSLog(#"error: %#",[error localizedDescription]);
}
may you are not authorising the location from user. thats why you are not getting anything
thanks
In my app(Deployment Target 5.1), i am using CoreLocation to setup a reminder feature, it will basically search the nearby items(have location attached) as device update its current location.
This feature is not working very stable at this stage, sometimes it just doesn't works at all regardless of whether device is in active, suspended and terminated states. i realized that the delegate method locationManager:didUpdateToLocation:fromLocation: didn't get call.
Is there anybody can point me a direction to make this thing work properly?
Here is my setup for the CLLocationManager
sharedLocationManager = [[CLLocationManager alloc]init];
[ESLocationManager defaultManager].delegate = someDelegateClassInstance;
[[ESLocationManager defaultManager] setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
[[ESLocationManager defaultManager] startMonitoringSignificantLocationChanges];
And the implementation of the delegate callback
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// If it's a relatively recent event, turn off updates to save power
NSDate* eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 20.0) {
// If the event is recent,find nearby items.
NSLog(#"latitude %+.6f, longitude %+.6f\n",
newLocation.coordinate.latitude,
newLocation.coordinate.longitude);
//reload nearby list
NSArray *nearbyItems = [self nearbyItemsForLocation:newLocation];
if (nearbyItems && nearbyItems.count ) {
UIApplicationState appState = [[UIApplication sharedApplication] applicationState];
if (appState != UIApplicationStateActive) {
[[UIApplication sharedApplication] presentLocalNotificationNow:[self localNotificationForItems:nearbyItems]];
}
}
}
}
Similar reason to this forum with region monitoring
https://devforums.apple.com/message/251046#251046
Hope this helps
How can I calculate real time speed on device? I've googled a lot but all I got is to calculate distance and speed after completion of journey. Can I calculate speed at runtime?
Suggestions will be much appreciated.
Thanks in advance.
here CLLocationManager class provide different field of location like, Latitude, Longitude,accuracy and speed.
i use CoreLocationController so for location update i call this bellow method
you can get current speed in - (void)locationUpdate:(CLLocation *)location method like bellow
- (void)locationUpdate:(CLLocation *)location
{
NSString *currentspeed = [NSString stringWithFormat:#"SPEED: %f", [location speed]];
}
or otherwise bellow is delegate method
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"in update to location");
NSString *currentspeed = [NSString stringWithFormat:#"SPEED: %f", [newLocation speed]];
}
also you can get example from this link...
http://www.vellios.com/2010/08/16/core-location-gps-tutorial/
i hope this help you...
:)
There is a delegate CLLocationManagerDelegate add it to your controller header file.
Initialize Location Manager and set the delegate where you implement the delegate method for location Manager like this
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self; // send loc updates to current class
and you can write method in your class
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog(#"Location Speed: %f", newLocation.speed);
}
That's it you will get your location updates in the above method with the speed also, and it will trigger as frequent as possible.
I have a CoreLocation manager in VC, when user pressed "get direction" button, I initalize location manager, and app opens google map direction with current location and some pre defined destination location.
Here is my problem, if app is not in background state, current location nearly always true, bu if app calling from background in same VC and user pressed again "get direction" button , current location generally shows old locations. In short, I'm troubling with multitasking and timestamp of retrieved locations did not solved my problem.
IBAction:
if ( self.locationManager ) {
[_locationManager release];
self.locationManager = nil;
}
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationTimer = [NSTimer scheduledTimerWithTimeInterval:LOCATION_TIMER target:self selector:#selector(stopUpdatingLocationTimer) userInfo:nil repeats:NO];
HUD = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
[self.locationManager startUpdatingLocation];
Core Location Delegate:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
NSLog(#"%f",locationAge);
if (locationAge > 3.0)
return;
if (newLocation.horizontalAccuracy < 0)
return;
if ( self.currentLocation == nil || self.currentLocation.horizontalAccuracy > newLocation.horizontalAccuracy ) {
self.currentLocation = newLocation;
if (self.currentLocation.horizontalAccuracy <= self.locationManager.desiredAccuracy) {
[self stopUpdatingLocations:YES];
}
}
}
In your example locationAge is a negative representation of the number of seconds since the timestamp of newLocation. This means that locationAge will never be greater than 3 and you're effectively letting every update through the sieve.
Set locationAge like this:
NSTimeInterval locationAge = [newLocation.timestamp timeIntervalSinceNow];
For those who encounter same problem,
Also, some tutorials related with core location on web, lead me this problem.
Of course, I keep CLLocation ivar in my VC, whenever CLLocation ivar
sets and google maps called, my app goes to background.
Then, my app calls from background by user, and start updating locations,
and old CLLocation ivar is not nil and probably best horizantal accuracy then
newly comes. Therefore;
if ( self.currentLocation == nil || self.currentLocation.horizontalAccuracy > newLocation.horizontalAccuracy )
this line cause problems, and old location in CLLocation ivar
never replaced.
So I changed viewDidDisappear like this and I assigned nil value to CLLocation variable and works perfectly.
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[self.locationManager stopUpdatingLocation]; // CLLocationManager
self.locationManager = nil;
[self.locationTimer invalidate]; // NSTimer
self.locationTimer = nil;
self.currentLocation = nil; // CLLocation
}
p.s : thank you Mark Adams