Sending location to server with CLLocationManager when iphone is in background - iphone

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.

Related

location monitoring in a iphone app

I am an newbie with iphone app development. I would like to capture location information without using GPS but only with Cell tower info and Wifi data. To enable this I am using the CLLocationManager to capture location information,
self.locationManager = [[CLLocationManager alloc] init];
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startMonitoringSignificantLocationChanges];
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *newLocation = [locations lastObject];
float latitude = newLocation.coordinate.latitude;
float longitude = newLocation.coordinate.longitude;
NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
// NSTimeInterval is defined as double
NSNumber *timeStampObj = [NSNumber numberWithDouble: timeStamp];
NSLog(#"latitude %f and longitude %f", latitude, longitude );
NSLog(#"%d", [timeStampObj integerValue]);
NSMutableArray *numArray = [[NSMutableArray alloc]initWithObjects:[NSNumber numberWithDouble:latitude],[NSNumber numberWithDouble:longitude], timeStampObj, nil];
}
When I use the above code when the app is launched I see that the app requests for accessing location services. Once this is accepted, I am not sure if the app is making use of GPS to get the location information as I see a small arrow pointing out, which seems as though GPS is being used to obtain the location information, which is not what I require. I would want the location information to be captured using WiFi and Cell Tower information only.
Also is there a frequency in which this location information gets updated, as there is an initial update of location after that I do not see the location getting modified even after the phone is being continuously moved.
If you use this:
[locationManager startMonitoringSignificantLocationChanges];
You are only getting GPS uploads when a significant change happens (for example, when you move from a telephony tower to other).
You cannot choose if you want to use GPS or towers from the code.

deferredLocationUpdate iOS 6

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

CLLocationManagerDelegate, when will the method be invoke: locationManager:didUpdateToLocation:fromLocation:

in CLLocationManagerDelegate, when will the method be invoke: locationManager:didUpdateToLocation:fromLocation:
could you explain more detail, if possible could you explain with example? thanks very much
if my current location is changing(eg, I am on a train), does this method be invoked? if yes, how many times or how frequently it is be invoked?
if I stay at one place and not move, does this method be invoked? if yes, how many times or how frequently it is be invoked?
This method is called whenever your iOS device has moved past the distance filter you have set. For example if you set it to
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
The method will be called every time the device is moved.
A code example of this would be finding the coordinates then assigning those values to labels
- (void)viewDidLoad{
[super viewDidLoad];
altitudeLabel.text = #"0 ft";
ftOrM = YES;
// Note: we are using Core Location directly to get the user location updates.
// We could normally use MKMapView's user location update delegation but this does not work in
// the background. Plus we want "kCLLocationAccuracyBestForNavigation" which gives us a better accuracy.
//
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self; // Tells the location manager to send updates to this object
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBestForNavigation];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
[self.locationManager startUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation: (CLLocation*)newLocation fromLocation:(CLLocation *)oldLocation {
tLatitude = [NSString stringWithFormat:#"%3.5f", newLocation.coordinate.latitude];
tLongitude = [NSString stringWithFormat:#"%3.5f", newLocation.coordinate.longitude];
/* the following returns 0 */
float distanceMeters;
float distanceFeet;
if (ftOrM == YES) {
distanceMeters = newLocation.altitude;
distanceFeet = distanceMeters * 3.2808399;
tAltitude = [NSString stringWithFormat:#"%.02f ft", distanceFeet];
altitudeLabel.text = tAltitude;
}
else {
tAltitude = [NSString stringWithFormat:#"%.02f m", newLocation.altitude];
NSLog(#"Altitude:");
NSLog(#"%#", tAltitude);
altitudeLabel.text = tAltitude;
NSLog(#"Altitude:");
NSLog(#"%#", tAltitude);
}
//[manager stopUpdatingLocation];
}
For the first one this method will invoked, and the frequency depends on the speed.
And if don't change your location then this method will not invoked.
And how much time your location is changing this method will call.

Returning a users lat lng as a string iPhone

Is there a way to return the users location as a string from a model?
I have a model thats job is to download same JSON data from a web service. When sending in my request I need to add ?lat=LAT_HERE&lng=LNG_HERE to the end of the string.
I have seen tons of examples using the map or constantly updating a label. But I cant find out how to explicitly return the lat and lng values.
Im only 2 days into iPhone dev so go easy on me :)
You need to leverage Core Location, specifically CLLocationManager. Apple doesn't provide any CL programming guide, so just look at one of the samples like LocateMe to see how to do it.
You need to use CLLocationManager like this:
- (void)viewDidLoad
{
// this creates the CCLocationManager that will find your current location
CLLocationManager *locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
}
// this delegate is called when the app successfully finds your current location
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
// retrieve lat and lng in a string from newLocation.coordinate
NSString *lat = [NSString stringWithFormat:#"%d", newLocation.coordinate.latitude];
NSString *lng = [NSString stringWithFormat:#"%d", newLocation.coordinate.longitude];
}
// this delegate method is called if an error occurs in locating your current location
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"locationManager:%# didFailWithError:%#", manager, error);
}

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.