Getting user coordinates every X seconds while application is in background - iphone

I want to get user coordinates every X seconds.
I added locations getting in app delegate.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if([CLLocationManager locationServicesEnabled]){
[self.locationManager startUpdatingLocation];
}
...
Here I handle new coordinates
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *loc = [locations objectAtIndex:0];
NSDate* eventDate = loc.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (howRecent < 10)
{
CLLocation* location = [locations lastObject];
double lat = location.coordinate.latitude;
double lng = location.coordinate.longitude;
NSLog(#"lat:%f lng:%f", lat, lng);
...
But I don't know how to continue getting iPhone coordinates when app is in background.
I suppose that I should add some code in:
- (void)applicationDidEnterBackground:(UIApplication *)application...
But I don't know what to do to keep location getting a live?

In your info.plist:
R.Click -> add a row and choose Required background modes-> and at item 0 choose App registers for location updates

Related

How can i achieve the accurate and same lat long even when i revisit the same place

I want this functionality to achieve, that when the user repeats the visit to same place suppose a person moves one meter forward then one meter back. He should get the same lat long value what he gets his previous time. I mean to accuracy for every footstep the user takes with device. How can i achieve this. Currently i am using CLLocationManager but it is giving the difference of 20 to 30 points at last in lat long when i moves at same place again.
Please help. Thanks in advance.
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyBest; // 100 m
locationManager.distanceFilter = 0.1f;
locationManager.delegate = self;
[locationManager startUpdatingLocation];
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSDate *locationTimeStamp = newLocation.timestamp;
NSTimeInterval delta = [locationTimeStamp timeIntervalSinceNow];
NSLog(#"The location timestamp interval was %f seconds.", delta);
_latitude.text = [NSString stringWithFormat:#"%f",newLocation.coordinate.latitude];
_longitude.text = [NSString stringWithFormat:#"%f",newLocation.coordinate.longitude];
_time.text = [NSString stringWithFormat:#"%f",delta];
}

Incorrect distance and route found in my walking/running app

I am working on this walking/running app which calculates distance in meters and records lat-long for further use. Now when I calculate distance I get incorrect distance every time. I have compared it with other running apps and they generally show different distance than my distance.
Here is the code that I am using:
#define kDesiredAccuracy 5.0f
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.locationManager.distanceFilter = kDesiredAccuracy;
_routes = [[NSMutableArray alloc] init];
lastKnownLocation = nil;
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
// return if accuracy is less than 0 or is greater than desired accuracy.
if (newLocation.horizontalAccuracy < 0)
{
return;
}
if(newLocation.horizontalAccuracy > kDesiredAccuracy)
{
return;
}
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
CLLocationSpeed speed = [newLocation speed];
// return if stale data or user is not moving
if (locationAge > 5.0 || speed <= 0) return;
//return if first location is found
if(lastKnownLocation == nil)
{
lastKnownLocation = newLocation;
return;
}
CLLocationDistance distance = [newLocation distanceFromLocation:(self.pramDistance > 0)?lastKnownLocation:oldLocation];
if(distance > 0)
{
// save distance for future use
NSMutableDictionary *dict=[[NSMutableDictionary alloc] init];
[dict setObject:[NSString stringWithFormat:#"%g", newLocation.coordinate.latitude] forKey:#"latitude"];
[dict setObject:[NSString stringWithFormat:#"%g", newLocation.coordinate.longitude] forKey:#"longtitude"];
[dict setObject:[NSString stringWithFormat:#"%f",distance] forKey:#"distance"];
[_routes addObject:dict];
// add distance to total distance.
self.pramDistance += distance;
}
}
Once user finishes walking/running I draw rout of walk/run on map view. For this purpose I simply draw a ploy line over MKMapView using all the recorded locations.
The map view shows zig-zag line for route and distance is always incorrect. Please suggest me where I am doing wrong and what should I amend to make it work proper?
Here is the comparison (left one is other's app and right one is mine):
Try this,
Import CLLocationManagerDelegate,
CLLocation *currentLocation = self.currentLocation;
float distanceMile = [currentLocation distanceFromLocation:[[CLLocation alloc] initWithLatitude:latitude longitude:longitude]]/1609.34;
-(void)postCurrentLocationOfDevice
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
self.locationManager.delegate = self;
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
self.currentLocation = [locations objectAtIndex:0];
[self.locationManager stopUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
self.currentLocation = newLocation;
[self.locationManager stopUpdatingLocation];
}
Though I didn't get much of the help here, I found some help and idea in this question: Corelocation incorrect distances
What I did to fix the problem is:
I stored recent 5 locations in an array.
Once 5 items are stored in the array, I checked for the nearest location.
After getting nearest location I calculated distance between last best location and stored new location in last best location.
P.S.: My code is messy and naming conventions are not that generic, that's why I am not posting my code here.

Cannot get GPS location on iPhone

My app runs perfectly on the simulator and everything works fine. But now i wanted to thest it on my iPhone and i found out that the GPS funcution don't work.
Here is my code.
[super viewDidLoad];
//eigener Standort
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
eigLat = newLocation.coordinate.latitude;
eigLon = newLocation.coordinate.longitude;
eigLatString = [NSString stringWithFormat:#"%f", eigLat];
eigLonString = [NSString stringWithFormat:#"%f", eigLon];
}
And till now everything is fine. If i use NSLog i get the right coordinates.
But then i want to use my coordinates here:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
news = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:NULL];
for (x=0; x<[news count]; x++)
{
//Berechnung der Entfernung
erdradius = 6371.1;
//Koordinaten von Datenbank in String schreiben
NSString *latitude = [[news objectAtIndex:x] objectForKey:#"Latitude"];
NSString *longitude = [[news objectAtIndex:x] objectForKey:#"Longitude"];
entfernung = 0;
double lat1 = eigLat; //eigener Standort Latitude
double long1 = eigLon; //eigener Standort Longitude
double lat2 = [latitude doubleValue]; //Standort Heurigen Latitude
double long2 = [longitude doubleValue]; //Standort Heurigen Longitude
And there I get everytime 0 for lat1 and lat2. But only if I Run the App on the iPhone. On the Simulator it works fine.
Does someone know why this could be?
The problem is that you did not get yet a GPS location in real world, so
your method connectionDidFinishLoading() is called before didUpdateToLocation() was called.
Therefoe eighValue is still 0.
Check first for valid lat and longitude:
if both are 0 then you did not get a location.
I think that you must change the logic of your program code,
you have to either
1) wait till you have a location, and then start the
connection such that connectionDidFinishLoading is called after you have a GPS coordinate.
Or
2) you store the coordinate result of the network connection, and calculate when you got your first coordinate

How to get device current latitude and longitude for IPhone device

I'm developing an app were I would like to get device current latitude and longitude for IPhone. Is it possible to obtain this information without using GPS.
Thanks
you can use CoreLocation framework
The Core Location framework has one important class CLLocationManager.
The CLLocationManager class handles sending out updates to a delegate anytime the location is changed. it uses the delegate CLLocationManagerDelegate protocol.
you can use it like
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController
<CLLocationManagerDelegate>
{
CLLocationManager *locationManager;
}
set up locationManager like this in viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
}
implement the below delegate mehod for getting changed location
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSInteger degrees = newLocation.coordinate.latitude;
double decimal = fabs(newLocation.coordinate.latitude - degrees);
int minutes = decimal * 60;
double seconds = decimal * 3600 - minutes * 60;
NSString *lattitudeStr = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
lattitudeLabel.text = lattitudeStr;
degrees = newLocation.coordinate.longitude;
decimal = fabs(newLocation.coordinate.longitude - degrees);
minutes = decimal * 60;
seconds = decimal * 3600 - minutes * 60;
NSString *longitudeStr = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
longitudeLabel.text = longitudeStr;
}
You can use CLLocationManager to get current lat and long.
create an iVar of CLLocationManager and use it.
Here is the code:
- (void)viewDidLoad
{
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog(#"OldLocation %f %f", oldLocation.coordinate.latitude, oldLocation.coordinate.longitude);
NSLog(#"NewLocation %f %f", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
currentLat = [NSString stringWithFormat:#"%f",newLocation.coordinate.latitude];
currentLong = [NSString stringWithFormat:#"%f",newLocation.coordinate.longitude];
}
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
CLLocation* currentLocation = [locationManager location];
NSString *loc = [NSString stringWithFormat:#"%f,%f",currentLocation.coordinate.latitude, currentLocation.coordinate.longitude];
NSLog(#"location:%#", loc);
You can get current location without GPS by using CLLocationManager if the device has WiFi or cellular data service. The location will not be as accurate as you would get from GPS but you get a result faster than from GPS.
You can request a non-GPS location from CLLocationManager by setting the desiredAccuracy property to kCLLocationAccuracyKilometer.
Using Swift
import CoreLocation
Get current location
let locationManager = CLLocationManager()
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.desiredAccuracy = kCLLocationAccuracyBest
//get the most recently retrieved user location
if let currentLocation = locationManager.location {
let longitude = currentLocation.coordinate.longitude
let latitude = currentLocation.coordinate.latitude
//work with the received data
}
Note that locationManager.location is an optional and hence should be safely unwrapped.

how to find latitude and longitude of different locatoins in iphone

I am a new iphone developer,please help me to find out latitude and longitude of different locations(present location values, distance 10m form present locatoin)and find address of that locations using that latitude and longituse values.
using mapkit framework you can find the current location along with near by location with their latitude & longitude
CLLocationCoordinate2D location;
location = [mMapView.userLocation coordinate];
if(iLat && iLng) {
location.latitude = [iLat floatValue];
location.longitude = [iLng floatValue];
}
In order to find out lat & long use this link with complete instruction & sample
http://www.switchonthecode.com/tutorials/getting-your-location-in-an-iphone-application
And in order to get location address using latitude & longitude this can be done by MKReverseGeoCoder.... get in detail using following link
http://blog.objectgraph.com/index.php/2009/04/03/iphone-sdk-30-playing-with-map-kit-part-2/
If your new new to Iphone development, you might wanna return that phone and start developing on Android!
Na just kidding, this will work indeed:
CLLocationCoordinate2D location; location = [mMapView.userLocation coordinate];
if(iLat && iLng) {
location.latitude = [iLat floatValue];
location.longitude = [iLng floatValue];
}
What you want to do is called reverse geocoding. On iOS, this is easily done using MapKit's MKReverseGeocoder.
Here's what you need to do:
First, check if location services is enabled:
if ([CLLocationManager locationServicesEnabled])
[self findUserLocation];
Then in your findUserLocation method, instantiate your CLLocationManager and start receiving updates:
- (void)findUserLocation
{
CLLocationManager *locationManager_ = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracy{ChooseYourOptionHere};
[locationManager startUpdatingLocation];
}
You then implement this delegate method, which will get called every time an update is received. Check the current location's accuracy against your desired accuracy (set above), center the map if you are happy with it AND don't forget to stop the location manager from receiving updates:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
if ([newLocation horizontalAccuracy] < [manager desiredAccuracy])
{
// Accuracy is good enough, let's reverse geocode it
[manager stopUpdatingLocation];
[self reverseGeocodeWithCoordinate:newLocation.coordinate];
}
// else keep trying...
}
Once you're happy with the location accuracy, you can start the reverse geocoding process:
- (void)reverseGeocodeWithCoordinate:(CLLocationCoordinate*)coordinate
{
MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:coordinate];
geocoder.delegate = self;
[geocoder start];
}
And you will receive the response via delegate methods:
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error
{
geocoder.delegate = nil;
[geocoder autorelease];
// Reverse geocode failed, do something
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
geocoder.delegate = nil;
[geocoder autorelease];
// Reverse geocode worked, do something...
}