deferredLocationUpdate iOS 6 - iphone

I have looked up about 3 different pages on how this works. But, I could really use some help because I am getting kCLError = 15. Here is what I have so far then I will explain more.
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self]
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager startUpdatingLocation];
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *currentLocation = [locations lastObject];
NSLog(#"%#",[locations lastObject];
NSLog(#"%d",[CLLocationManager deferredLocationUpdatesAvailable]);
[locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:CLTimeIntervalMax];
After this I have my error code
-(void)locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error
{
NSString *stringError = [NSString stringWithFormat:#"error: %#",[error description]];
_whatMonitor.text = stringError;
}
So, anyone that can help me I will seriously be so thankful. I have a count of the locations array as well, but this never changes from 1.. It is my understanding that after closing app to home screen and locking the device, the deferredUpdates should kick in. I have checked the [locations count] and it is still 1. I am expecting it to be greater than this..
I do not claim to be very good at this, so if I am making a careless mistake please let me know. I did not copy and paste so there may be some small typos. Thanks in advance.
I am running iOS 6.0 on an iPhone 5.

For significant change service and deferred location updates you have to move for the system to record an update. You have specified CLLocationDistanceMax which is a high value for distance. You can specify a lower distance to get more frequent changes for example you could specify every 100 meter change to trigger an update as follows:
[locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocation(100) timeout:CLTimeIntervalMax];
Reference: http://developer.apple.com/library/ios/#documentation/CoreLocation/Reference/CLLocationManager_Class/CLLocationManager/CLLocationManager.html

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

Getting longitude,latitude without setting it all app life

I want simple get lan,lon valus at the time application start,I dont want to update every second those values as I am changing my possition. I am using this code:
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
latValueNSString = [NSString stringWithFormat: #"%f",newLocation.coordinate.latitude];
lanValueNSString = [NSString stringWithFormat: #"%f",newLocation.coordinate.longitude];
}
But the problem that I cant transfer those values because every millisecond its setting it again and again... how can i set those values only ones and that's it??
If you only need 1 value, just get the first location and tell the location manager to stop updating the location.
[manager stopUpdatingLocation];
do this when the delegate method is called.
Call [locationManager stopUpdatingLocation]; once you get a result. You may want to check if the accuracy is what you need before calling stop.

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.

Sending location to server with CLLocationManager when iphone is in background

i'm having trouble sending my position when the application lies in the background. I'm using CLLocationManager and startMonitoringSignificantLocationChanges. The posision didUpdateToLocation delegate method is performed once, but not more. I've tried to walk around but no new locations is sent to the server.
I have set the "Required background modes" -> "App registers for location updates" in the info.plist file.
Anyone got an idea on what might be wrong?
Code from where the tracking is started:
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = appDelegate;
[appDelegate setLocationManager:locationManager withDistanceFilter:kCLDistanceFilterNone];
[appDelegate.theLocationManager startMonitoringSignificantLocationChanges];
Code (from CLLocationManagerDelegate):
- (void)setLocationManager:(CLLocationManager*)locationManager withDistanceFilter:(CLLocationDistance)distanceFilter {
// create a new manager and start checking for sig changes
self.theLocationManager.delegate = nil;
[theLocationManager release];
self.theLocationManager = locationManager;
self.theLocationManager.delegate = self;
self.theLocationManager.distanceFilter = distanceFilter;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSDate *newLocationTimestamp = newLocation.timestamp;
NSDate *oldLocationTimestamp = oldLocation.timestamp;
int locationUpdateInterval = 15;//15 sec
if (!([newLocationTimestamp timeIntervalSinceDate:oldLocationTimestamp] < locationUpdateInterval)) {
//NSLog(#"New Location: %#", newLocation);
[self updateToLocation:newLocation];
}
}
- (void)updateToLocation:(CLLocation *)newLocation {
NSLog(#"update location!!");
NSString *latitude = [NSString stringWithFormat:#"%f", [newLocation coordinate].latitude];
NSString *longitude = [NSString stringWithFormat:#"%f", [newLocation coordinate].longitude];
[currentUser updatePositionWithLongitude:longitude andLatitude:latitude];
}
Like Bill Brasky said, the accuracy to which you have set your location manager is likely not registering the distance that you have walked. Try setting your location manager accuracy much higher, just to see if works, then dial it back down to a happy medium between accuracy and battery efficiency. Just for testing, take it all the way up:
[appDelegate.theLocationManager setDesiredAccuracy:kCLLocationAccuracyBestForNavigation];
Then instead of:
[appDelegate.theLocationManager startMonitoringSignificantLocationChanges];
try:
[appDelegate.theLocationManager startUpdatingLocation];
The -startMonitoringForSignificantLocationChanges is directly tied to cell tower connectivity. You may need to travel miles to get connection to a new tower and trigger a location change event. I know that the region monitoring is a bit more accurate as it uses updates of location from Wifi, cell tower, and even other apps that inquire on location. You will need to figure out how accurate and how often you need your app to be. You may need to actively monitor location in the background (which would be a battery killer for sure). Hope this helps.

CLLocationManger gives old location. How to get the new location?

I am using the CLLocationManger to update the current location. Though its giving me the location but the location I am getting is of much older timestamp. I am facing the problem in, how to force the locationcontroller to update the fresh location not the cached location.
Currently I am using this tutorial......
http://www.mobileorchard.com/hello-there-a-corelocation-tutorial/
Anybody know how to update location at current timestamp not the cached one?
Are you running your project on simulator or on iPhone? If you are running project on simulator then
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
will be called only once.
If you are testing on device then it should be called everytime your location is changed.
Make sure you have set the location manager property,
locationManager.delegate=self;
[locationManager startUpdatingLocation];
Hope that helps...
you can use this methods
- (IBAction)update {
locmanager = [[CLLocationManager alloc] init];
[locmanager setDelegate:self];
[locmanager setDesiredAccuracy:kCLLocationAccuracyBest];
NSLog(#"*********this is location update method of login view controller");
[locmanager startUpdatingLocation];
}
-(void)awakeFromNib {
[self update];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
if (wasFound) return;
wasFound = YES;
CLLocationCoordinate2D loc = [newLocation coordinate];
lat2 = [[NSString stringWithFormat: #"%f", loc.latitude]retain];
logg2= [[NSString stringWithFormat: #"%f", loc.longitude]retain];
NSLog(#"latitude is %#",lat2);
NSLog(#"longitude is %#",logg2);
}
call the update method using perform selector in viewdidload method.Here lat2 and logg2 are string values.
if problem can't be solved then type how to find current location in google.you will get many examples source code with explanation
The best you can do is throw out locations that are too old by whatever standard you decide to set for your app. Restarting the location manager is supposed to tell the system you want a new location, but usually the first location you get back may be whatever it had last. Checking the timestamp may be all you can do, but be prepared for the possibility that you may never get a newer location. I've seen in my experience that if the device hasn't moved, it never bothers to update the system with a new location if it detects that the current location is good enough.