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.
Related
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 add some annotations to my mkMapView in this loop:
for (PFObject *fetchedCompany in companyArray)
{
Store *store = [[Store alloc] initWithObject:fetchedCompany];
[self loadStore:store];
[store release];
}
- (void) loadStore:(Store *) store {
CLLocationCoordinate2D location = [self getLocationFromAddressString:store.address];
MapViewAnnotation *mapAnnotation = [[MapViewAnnotation alloc] initWithTitle:store.name coordinate:location];
[self.indexMapView addAnnotation:mapAnnotation];
}
And this the getLocationFromAddressString method that convert the address to a location using google api:
-(CLLocationCoordinate2D) getLocationFromAddressString:(NSString*) addressStr {
NSString *urlStr = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv", [addressStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSError *error = nil;
NSString *locationStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlStr] encoding:NSUTF8StringEncoding error:&error];
NSArray *items = [locationStr componentsSeparatedByString:#","];
double lat = 0.0;
double lon = 0.0;
if([items count] >= 4 && [[items objectAtIndex:0] isEqualToString:#"200"]) {
lat = [[items objectAtIndex:2] doubleValue];
lon = [[items objectAtIndex:3] doubleValue];
}
else {
NSLog(#"Address, %# not found: Error %#",addressStr, [items objectAtIndex:0]);
}
CLLocationCoordinate2D location;
location.latitude = lat;
location.longitude = lon;
return location;
}
When I send just one location always it works perfectly, but when I add annotations in my loop sometimes some locations could not be recognized and I got the error from my NSLog:
Address, Vallgatan 3 GÖTEBORG not found: Error 620
The thing is I am pretty sure about the addresses because when I tried them without loop they worked. Do you know how can I solve the problem?
You've submitted too many queries and your request got rejected. See Geocoding API V2 docs.
620: G_GEO_TOO_MANY_QUERIES
"The given key has gone over the requests limit in the 24 hour period or has submitted too many requests in too short a period of time. If you're sending multiple requests in parallel or in a tight loop, use a timer or pause in your code to make sure you don't send the requests too quickly"
I have a method in my appDelegate which gets latitude and longitude and returns a string which I can use in any viewController.
AppDelegate :
-(void)StartUpdating
{
locManager = [[CLLocationManager alloc] init];
locManager.delegate = self;
locManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locManager startUpdatingLocation];
}
#pragma mark
#pragma mark locationManager delegate methods
- (void)locationManager: (CLLocationManager *)manager
didUpdateToLocation: (CLLocation *)newLocation
fromLocation: (CLLocation *)oldLocation
{
float latitude = newLocation.coordinate.latitude;
strLatitude = [NSString stringWithFormat:#"%f",latitude];
float longitude = newLocation.coordinate.longitude;
strLongitude = [NSString stringWithFormat:#"%f", longitude];
//[self returnLatLongString:strLatitude:strLongitude];
}
-(NSString*)returnLatLongString
{
NSString *str = #"lat=";
str = [str stringByAppendingString:strLatitude];
str = [str stringByAppendingString:#"&long="];
str = [str stringByAppendingString:strLongitude];
return str;
}
I am calling StartUpdating in start of application. Now in my viewController I call this method:
AppDelegate *appDelegate=[AppDelegate sharedAppDelegate];
NSString *str = [appDelegate returnLatLongString];
But I get a crash in
str = [str stringByAppendingString:strLatitude];
in returnLatLongString.
I know I am getting crash because there is no value in strLatitude at that time. But how can I fix this? How can I still have updated value of latitude and longitude?
Also, I don't want to use locationManager in viewControllers. So that I can get current location in all viewControllers, I did it in appDelegate.
The crash might be because str is an NSString, and so therefore is not mutable. Assigning it back to itself in this case is problematic. It would be simpler just to use stringWithFormat:
NSString *str = [NSString stringWithFormat: #"lat=%#&long=%#", strLatitude, strLongitude];
Import your AppDelegate.h file. Then
Use the following code:
MyAppDelegate *myAppDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *result = [myAppDelegate returnLatLongString];
i think you need to init those variables (strLatitude, strLongitude) in your
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method. if it hits this point at first time, they are not initialized so you get crash.
There are two potential problems in your code.
First of all make sure you declare strLatitude and strLongitude as strong properties in your header file:
#property (nonatomic, strong) NSString * strLatitude;
#property (nonatomic, strong) NSString * strLongitude;
Use #synthesize to automatically generate the proper getter and setter for them and assign the proper values to them as:
float latitude = newLocation.coordinate.latitude;
self.strLatitude = [NSString stringWithFormat:#"%f",latitude];
float longitude = newLocation.coordinate.longitude;
self.strLongitude = [NSString stringWithFormat:#"%f", longitude];
to make sure that they don't get released after they are assigned a value, because [NSString stringWithFormat:] returns autoreleased objects.
Secondly, after [locManager startUpdatingLocation]; it's going to take sometime before the system delivers the first location update. Therefore you need to check if the strLatitude and strLongitude have already been assigned values before you try to construct another string with them. Something similar to this should do the job:
-(NSString*)returnLatLongString
{
if (self.strLatitude == nil || self.strLongitude == nil)
return nil;
NSString *str = #"lat=";
str = [str stringByAppendingString:strLatitude];
str = [str stringByAppendingString:#"&long="];
str = [str stringByAppendingString:strLongitude];
return str;
}
Then of course the view controllers who are going to use [AppDelegate returnLatLongString] need to check that the returned value is not nil.
Hope this helps...
You are doing a mistake with creating a object of AppDelegate Class..
To create object just write this code :
AppDelegate *appDelegate=(AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *str = [appDelegate returnLatLongString];
Its done..
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’.”
I am having issues with zero's
If my stings contain zeros or nothing the 3rd control view crashed the app.
Any ideas
- (void)viewDidLoad {
appDelegate= (TemplateIponeAppDelegate *)[UIApplication sharedApplication].delegate;
if ([MFMailComposeViewController canSendMail])
mailButton.enabled = YES;
rResults.text = [NSString stringWithFormat:#"R Resultes: %d",appDelegate.RCount];
bResults.text=[NSString stringWithFormat: #"B Resultes: %d",appDelegate.BCount];
pResults.text=[NSString stringWithFormat: #"P Resultes: %d",appDelegate.PCount];
fResults.text=[NSString stringWithFormat: #"F Resultes: %d",appDelegate.FCount];
totalResults.text=[NSString stringWithFormat: #"Total R-P-B: %d",appDelegate.TotalPressed];
rightCount = appDelegate.RCount + appDelegate.BCount+appDelegate.PCount;
grandtotal.text=[NSString stringWithFormat: #"Total : %d",rightCount];
ratiocount= (appDelegate.RCount + appDelegate.BCount+appDelegate.PCount) /appDelegate.FCount;
ratiototal.text = [NSString stringWithFormat: #"Total : %d",appDelegate.FCount];
[super viewDidLoad];
Your problem is this line,
ratiocount= (appDelegate.RCount + appDelegate.BCount+appDelegate.PCount) /appDelegate.FCount;
if appDelegate.FCount is zero, then this will result in an error. You should put some kind of a check on it.