I am developing for jailbreak iPhones. I am reading Beginning iOS 5 book. Currently, I have used a location code from the book and changed it slightly. The change which I have made in the code is that I am writing the location in a text file. But the program crashes. Although the same program without any modification is working perfectly.
Here is the code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = 2.0f;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
FILE *file = fopen("/usr/locations.txt", "a");
if (!file)
{
fprintf(file, "Error opening file");
}
if (startingPoint == nil)
self.startingPoint = newLocation;
NSString *latitudeString = [NSString stringWithFormat:#"%g\u00B0",
newLocation.coordinate.latitude];
latitudeLabel.text = latitudeString;
NSNumber *latitude = [[NSNumber alloc] initWithDouble:newLocation.coordinate.latitude];
NSNumber *longitude = [[NSNumber alloc] initWithDouble:newLocation.coordinate.longitude];
NSString *longitudeString = [NSString stringWithFormat:#"%g\u00B0",
newLocation.coordinate.longitude];
longitudeLabel.text = longitudeString;
NSString *horizontalAccuracyString = [NSString stringWithFormat:#"%gm",
newLocation.horizontalAccuracy];
horizontalAccuracyLabel.text = horizontalAccuracyString;
NSString *altitudeString = [NSString stringWithFormat:#"%gm",
newLocation.altitude];
altitudeLabel.text = altitudeString;
NSString *verticalAccuracyString = [NSString stringWithFormat:#"%gm",
newLocation.verticalAccuracy];
verticalAccuracyLabel.text = verticalAccuracyString;
CLLocationDistance distance = [newLocation
distanceFromLocation:startingPoint];
NSString *distanceString = [NSString stringWithFormat:#"%gm", distance];
distanceTraveledLabel.text = distanceString;
struct tm *local;
time_t t;
t = time(NULL);
local = localtime(&t);
fprintf(file, "Local time and Date: %s ", asctime(local));
//----------------- ------------------------------------------------------------
fprintf(file, "Latitude = %lf, Longitude = %lf \n",
newLocation.coordinate.latitude, newLocation.coordinate.longitude);
fclose(file);
}
Your most recent comment on the question says you want to print to the console instead. In order to print on the console you use NSLog(). When you use the format specifier for an object %#, the string substituted for the object is the object’s description method.
To print the location on the console use
NSLog(#"New location: %#", newLocation);
NSLog(#"Old location: %#", oldLocation);
The description method on CLLocation returns “A string of the form ‘latitude, longitude +/- accuracy m (speed kph / heading) # date-time’.”
Related
I am developing an iPhone app which uses location services and runs in background.This app displays latitude and longitude exactly when it runs on IOS6.But if i run the same app on IOS7, sometimes it shows latitude and longitude exactly, sometimes -1 and -1. I'm not understanding this behaviour on IOS7. what may be the reason for this behaviour?
In order to simulate a location, select the iOS Simulator Debug -> Location menu option and select either one of the pre-defined locations or journeys (such as City Bicycle Ride), or Custom Location… to enter a specific latitude and longitude.
This code worked for me.
Creating the CLLocationManager Object
The next task is to implement the code to create an instance of the CLLocationManager class. Since this needs to occur when the view loads, an ideal location is in the view controller’s viewDidLoad method in the LocationViewController.m file:
- (void)viewDidLoad {
[super viewDidLoad];
_locationManager = [[CLLocationManager alloc] init];
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
_locationManager.delegate = self;
[_locationManager startUpdatingLocation];
_startLocation = nil;
}
Implementing the Action Method
-(void)resetDistance:(id)sender
{
_startLocation = nil;
}
Implementing the CLLocationManager Method
#pragma mark -
#pragma mark CLLocationManagerDelegate
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSString *currentLatitude = [[NSString alloc]
initWithFormat:#"%+.6f",
newLocation.coordinate.latitude];
_latitude.text = currentLatitude;
NSString *currentLongitude = [[NSString alloc]
initWithFormat:#"%+.6f",
newLocation.coordinate.longitude];
_longitude.text = currentLongitude;
NSString *currentHorizontalAccuracy =
[[NSString alloc]
initWithFormat:#"%+.6f",
newLocation.horizontalAccuracy];
_horizontalAccuracy.text = currentHorizontalAccuracy;
NSString *currentAltitude = [[NSString alloc]
initWithFormat:#"%+.6f",
newLocation.altitude];
_altitude.text = currentAltitude;
NSString *currentVerticalAccuracy =
[[NSString alloc]
initWithFormat:#"%+.6f",
newLocation.verticalAccuracy];
_verticalAccuracy.text = currentVerticalAccuracy;
if (_startLocation == nil)
_startLocation = newLocation;
CLLocationDistance distanceBetween = [newLocation
distanceFromLocation:_startLocation];
NSString *tripString = [[NSString alloc]
initWithFormat:#"%f",
distanceBetween];
_distance.text = tripString;
}
In the End Try this method
Try this method to get continuous updated latitude and longitude
(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *location_updated = [locations lastObject];
NSLog(#"updated coordinate are %#",location_updated);
}
Use this method for getting location continuously use this method
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
location_updated = [locations lastObject];
NSLog(#"updated coordinate are %#",location_updated);
}
may be you are using this method
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
This method has been Deprecated in iOS 6.0
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.
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
I am trying to find distance from selectedAnnotation to userLocation. I added the following code in the annotation NSObject:
-(void) setDistanceFromCurrentLocation:(CLLocation *)currentLocation{
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:self.latitude longitude:self.longitude];
[self setDistance:[currentLocation distanceFromLocation:location2]];
}
- (NSString *)subtitle
{
NSString *myDistance = [NSString stringWithFormat:#"%1.1f from current location", distance];
return myDistance;
}
Now in the didUpdatedidUpdateToLocation I tried using the following logic from this question: https://stackoverflow.com/a/10881683/984248
Still getting 0.0 back. What am I doing wrong?
EDIT:
So I am calculating the distance from current location correctly now. But how do I pass this on to set it as the subtitle to a pin?
Here is how I am finding distance:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[self setCurrentLocation:newLocation];
// if not Current Location then update the currently displayed Dealer Annotation
for (int i=0; i<self.dataArray.count; i++){
NSDictionary *dataDictionary = [self.dataArray objectAtIndex:i];
NSArray *array = [dataDictionary objectForKey:#"Locations"];
for (int i=0; i<array.count; i++){
NSMutableDictionary *dictionary = [array objectAtIndex:i];
CLLocation *pinLocation = [[CLLocation alloc] initWithLatitude:[[dictionary objectForKey:#"Latitude"] doubleValue] longitude:[[dictionary objectForKey:#"Longitude"] doubleValue]];
[?????? setDistance:[self.currentLocation distanceFromLocation:pinLocation]];
}
}
}
Here is how I am adding pins to the map:
for (int i=0; i<self.dataArray.count; i++){
NSDictionary *dataDictionary = [self.dataArray objectAtIndex:i];
NSArray *array = [dataDictionary objectForKey:#"Locations"];
for (int i=0; i<array.count; i++){
NSMutableDictionary *dictionary = [array objectAtIndex:i];
MapAnnotation *annotation = [[MapAnnotation alloc] init];
annotation.latitude = [[dictionary objectForKey:#"Latitude"] doubleValue];
annotation.longitude = [[dictionary objectForKey:#"Longitude"] doubleValue];
CLLocationCoordinate2D coord = {.latitude =
annotation.latitude, .longitude = annotation.longitude};
MKCoordinateRegion region = {coord};
annotation.title = [dictionary objectForKey:#"Name"];
annotation.subtitle = ?????;
annotation.coordinate = region.center;
//Saving the dictionary of the pin to show contact info later
annotation.sourceDictionary = dictionary;
[mapView addAnnotation:annotation];
}
}
Just wondering, is currentLocation set to self.latitude,self.longitude?
in which case you would be trying to find the distance from yourself. Try logging the latitude and longitude values of the currentLocation parameter and the self.latitude and self.longitude variables, and make sure they are different.
If they are, then try logging [currentLocation distanceFromLocation:location2] to see if it is non zero, if it is, then your setDistance method is the problem.
Other than that all I can think of is your distance variable is getting set to 0 somewhere else, or it is a variable that does not format with %1.1f so the formatter is setting it to 0.0
I have written the following code to find the current location.
It works well and prints the current location when I print lat2 and logg2 below in NSLOg, but it is not assigning value to lables. When I print label the value is null.
And I want to access lat2 and logg2 values outside the method didUpdateToLocation.
I am not able to access these values outside the didUpdateToLocation method even though
I have declared logg2 and lat2 globally. Outside this method it gives null value. How can I do that? What is problem here? Is there any sample code or tutorial fot that?
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
-(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];
logg2= [NSString stringWithFormat: #"%f", loc.longitude];
NSLog(#"latitude is %#",lat2);
NSLog(#"longitude is %#",logg2);
NSLog(#"*******This is the login view controller did update locationmethod of loginview controller.");
NSLog(#"latitude is %f",[lat2 floatValue]);
NSLog(#"longitude is %f",[logg2 floatValue]);
labellat.text = [NSString stringWithFormat: #"%f", loc.latitude];
labellog.text= [NSString stringWithFormat: #"%f", loc.longitude];
//NSLog(#"text of label is %#",labellat.text);
//NSLog(#"text of label is %#",labellog.text);
//lat=loc.latitude;
//log=loc.longitude;
//altitude.text = [NSString stringWithFormat: #"%f", newLocation.altitude];
// NSString *mapUrl = [NSString stringWithFormat: #"http://maps.google.com/maps?q=%f,%f", loc.latitude, loc.longitude];
// NSURL *url = [NSURL URLWithString:mapUrl];
// [[UIApplication sharedApplication] openURL:url];
}
- (IBAction)update {
locmanager = [[CLLocationManager alloc] init];
[locmanager setDelegate:self];
[locmanager setDesiredAccuracy:kCLLocationAccuracyBest];
NSLog(#"*********This is the location update method of login view controller.");
[locmanager startUpdatingLocation];
}
Basic memory management:
lat2 = [NSString stringWithFormat: #"%f", loc.latitude];
logg2= [NSString stringWithFormat: #"%f", loc.longitude];
These strings are destroyed (deallocated) almost right after you create them. Read up on memory management guidelines. Don't use globals either. If you must, this should fix your strings disappearing:
[lat2 release];
[logg2 release];
lat2 = [[NSString stringWithFormat: #"%f", loc.latitude] retain]; // keep string alive until we release it
logg2= [[NSString stringWithFormat: #"%f", loc.longitude] retain];
Oh, and did you remember to connect the outlets to your labels in Interface Builder?
Use this to show your latitude and longitude in labels.
labellat.text = [NSString stringWithFormat: #"%.6f", loc.latitude];
labellog.text= [NSString stringWithFormat: #"%.6f", loc.longitude];
Please retain the location coordinate to get the values if you want call this from any other places, otherwise it may autorelase.
You can make use of
labellat.text = [NSString stringWithFormat: #"%#", lat2];
labellog.text= [NSString stringWithFormat: #"%#", logg2];
But I think it's better to store the latitude and longitude values as a float itself in an instance variable and thereby getting access to it easily. If you want to show it in a label, use the method stringWithFormat: just as you did.
UPDATE:
The tutorial Hello There: A CoreLocation Tutorial may help you.