I just started coding in Objective C, and am making an app that will track the users location, and send an alert with the latlng in it. This code isn't complete in the slightest, but I ran into a problem with trying to use the variable I created "lat" in the "viewDidLoad" for the alert. I declared the variable in the CLLocationManager delegate/method(I don't really know what it's called) and I don't know how to use it in other places.
- (void)viewDidLoad
{
locationManager =[[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = 100.0f;
[locationManager startUpdatingLocation];
UIAlertView *message = [[UIAlertView alloc] initWithTitle: #"Your current Latitude is:"
message:This is where I want to put the variable "lat"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void) locationmanager: (CLLocationManager *) manager
didUpdateToLocation: (CLLocation *) newLocation
fromLocation: (CLLocation *) oldLocation
{
NSString *lat = [[NSString alloc] initWithFormat: #"%g",newLocation.coordinate.latitude];
NSString *lng = [[NSString alloc] initWithFormat:#"%g", newLocation.coordinate.longitude];
}
Any help would be appreciated!
Simple solution.
Your ViewController .h should look something like this
#interface ViewController : UIViewController {
NSString *lat;
NSString *lng;
}
then this becomes
-(void) locationmanager: (CLLocationManager *) manager
didUpdateToLocation: (CLLocation *) newLocation
fromLocation: (CLLocation *) oldLocation
{
lat = [[NSString alloc] initWithFormat: #"%g",newLocation.coordinate.latitude];
lng = [[NSString alloc] initWithFormat:#"%g", newLocation.coordinate.longitude];
NSLog(lat);
NSLog(lng);
}
NSlog simple out puts to the console which is locate just below where you code
remove
UIAlertView *message = [[UIAlertView alloc] initWithTitle: #"Your current Latitude is:"
message:This is where I want to put the variable "lat"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
Because that will just show an alert as soon as the view is loaded
Hope this helps
Related
I am having difficulty implementing what I think should be a pretty simple capability. I have an button that compares the user's location to another set of lat/lon coordinates and displays an alert telling the user if they are "nearby" or "far away" from the location. This works well if the app remains in the foreground.
However, if the app gets sent to the background, the locationManager stops updating the user's location. If this happens, when the user brings the app back up and presses the "compare location button", the app doesn't seem to be able to get the user's new coordinates correctly.
Adding receive location updates to the background modes seems to work, but I know this will drain battery an may be rejected by Apple.
All I really want is to be able to have the button wait for an accurate set of lat/lon coordinates before trying to calculate the distance between the user and the other set lat/lon coordinates. Here is what I have so far:
The Location Button Does This:
-(void) locationButton {
NSString *userLatitude =[(PDCAppDelegate *)[UIApplication sharedApplication].delegate
getUserLatitude];
NSString *userLongitude =[(PDCAppDelegate *)[UIApplication sharedApplication].delegate
getUserLongitude];
NSString *placeLatitude = [[NSUserDefaults standardUserDefaults]
stringForKey:#"savedLatitude"];
NSString *placeLongitude = [[NSUserDefaults standardUserDefaults]
stringForKey:#"savedLongitude"];
NSString *distanceURL = [NSString stringWithFormat:#"http://www.website.com/page.php?
lat1=%#&lon1=%#&lat2=%#&lon2=%#",userLatitude, userLongitude, placeLatitude,
placeLongitude];
NSData *distanceURLResult = [NSData dataWithContentsOfURL:[NSURL
URLWithString:distanceURL]];
NSString *distanceInFeet = [[NSString alloc] initWithData:distanceURLResult
encoding:NSUTF8StringEncoding];
if ([distanceInFeet isEqualToString:#"1"]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"You're Near!"
message:#"" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
return;
}
if ([distanceInFeet isEqualToString:#"0"]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"You're Far!" message:#""
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
return;
}
}
The first few lines of the locationButton method get the userLatitude and userLongitude from my App Delegate:
- (NSString *)getUserCoordinates {
NSString *userCoordinates = [NSString stringWithFormat:#"latitude: %f longitude: %f",
locationManager.location.coordinate.latitude,
locationManager.location.coordinate.longitude];
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
return userCoordinates;
}
- (NSString *)getUserLatitude {
NSString *userLatitude = [NSString stringWithFormat:#"%f",
locationManager.location.coordinate.latitude];
return userLatitude;
}
- (NSString *)getUserLongitude {
NSString *userLongitude = [NSString stringWithFormat:#"%f",
locationManager.location.coordinate.longitude];
return userLongitude;
}
I am calling URL on my Search button event to load data. I have put the code for Loading indicator Alert view by taking NSThread. I am using 3.2 xcode with 4.3 iOS. Every thing run smooth but on search button it shows Loading indicator and then crashing and showing following in console
Program received signal: “EXC_BAD_ACCESS”.
warning: Unable to read symbols for /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.3.2 (8H7)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib (file not found).
Code under the Search Button click event:
- (IBAction) searchButton {
if([addressField.text length]==0)
{
UIAlertView *myAlert = [[[UIAlertView alloc] initWithTitle:#"Alert" message:#"Please Tap on 'Show Me' & choose the 'Radius' first!!!" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil] autorelease];
[myAlert show];
}
else
{
[NSThread detachNewThreadSelector:#selector(updateFilterProgress) toTarget:self withObject:nil];
appDelegate = (MapTutorialAppDelegate *)[[UIApplication sharedApplication] delegate];
CLLocationCoordinate2D location;
float radius = [[arrayNo objectAtIndex:[pickerView selectedRowInComponent:0]] floatValue];
NSString *url = [NSString stringWithFormat:#"http://....url...../hespdirectory/phpsqlsearch_genxml.php?lat=%f&lng=%f&radius=%f",locationManager.location.coordinate.latitude,locationManager.location.coordinate.longitude,radius];
NSLog(#"%#", url);
NSURL *URL = [NSURL URLWithString:url];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
//Initialize the delegate.
XMLParser *parser = [[XMLParser alloc] initXMLParser];
//Set delegate
[xmlParser setDelegate:parser];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
{
if([appDelegate.markers count] == 0){
UIAlertView *myAlert = [[[UIAlertView alloc] initWithTitle:#"Alert" message:#"No results fond!!!" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil] autorelease];
[myAlert show];
}
else
{
resultButton.userInteractionEnabled = YES;
for (int i = 0; i < [appDelegate.markers count]; i++)
{
marker *aMarker = [appDelegate.markers objectAtIndex:i];
location.latitude = [aMarker.lat floatValue];
location.longitude =[aMarker.lng floatValue];
AddressAnnotation *annob = [[AddressAnnotation alloc] initWithCoordinate:location];
annob.title = aMarker.name;
annob.subTitle = aMarker.address;
[mapView addAnnotation:annob];
[annob release];
CLLocationCoordinate2D ausLoc = {location.latitude,location.longitude}; //for zoom in the showroom results region
MKCoordinateSpan ausSpan = MKCoordinateSpanMake(0.108889, 0.169922);
MKCoordinateRegion ausRegion = MKCoordinateRegionMake(ausLoc, ausSpan);
NSLog(#"No Errors");
mapView.region = ausRegion;
}
}
}
else
NSLog(#"Error Error Error!!!");
[addressField resignFirstResponder];
}
}
And for NSThread to Show Loaading indicator while loading data at the back.
- (void) updateFilterProgress{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
Reachability *r = [Reachability reachabilityWithHostName:#"www.google.com"];
NetworkStatus internetStatus = [r currentReachabilityStatus];
if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
{
UIAlertView *myAlert = [[[UIAlertView alloc] initWithTitle:#"No Internet Connection" message:#"This app require an internet connection via WiFi or cellular network to work." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil] autorelease];
[myAlert show];
}
else{
UIAlertView *alertMe = [[[UIAlertView alloc] initWithTitle:#"Loading..." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil] autorelease];
[alertMe show];
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
// Adjust the indicator so it is up a few pixels from the bottom of the alert
indicator.center = CGPointMake(alertMe.bounds.size.width / 2, alertMe.bounds.size.height - 50);
[indicator startAnimating];
[alertMe addSubview:indicator];
[indicator release];
[alertMe release];
for (int i = 200; i > [appDelegate.markers count]; i--)
{
marker *aMarker = [appDelegate.markers objectAtIndex:i];
[alertMe dismissWithClickedButtonIndex:0 animated:YES];
}
}
[pool release]; }
Is there anything remaining in my code. Pleas correct me....
The variable alertMe is autoreleased and therefore you can't just send a release message to it. Remove the line [alertMe release]; and it will run perfectly.
You are probably accessing a released object. To see which one it is, set NSZombiesEnabled - this will show you which already released object you try to access, and you should be able to identify your problem.
Please have a look here to see how to enable the zombies in XCode 4:
http://42games.net/quick-note-on-setting-nszombieenabled-environment-variable-in-xcode-4/
For some reason, I cannot get the name of the city (locality) from my code. Please help!
- (void)viewDidLoad {
[super viewDidLoad];
self.lm = [[CLLocationManager alloc] init];
lm.delegate = self;
lm.desiredAccuracy = kCLLocationAccuracyBest;
lm.distanceFilter = kCLDistanceFilterNone;
[lm startUpdatingLocation];
}
- (void) locationManager:(CLLocationManager *)manager didUpdateToLocation: (CLLocation *) newLocation fromLocation: (CLLocation *)oldLocation {
if (!geocoder) {
geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate];
geocoder.delegate = self;
[geocoder start];
}
NSString *lat = [[NSString alloc] initWithFormat:#"%f", newLocation.coordinate.latitude];
NSString *lng = [[NSString alloc] initWithFormat:#"%f", newLocation.coordinate.longitude];
NSString *acc = [[NSString alloc] initWithFormat:#"%f", newLocation.horizontalAccuracy];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:lat message:lng delegate:self cancelButtonTitle:acc otherButtonTitles: #"button", nil];
[alert show];
[alert release];
[lat, lng, acc release];
}
- (void) reverseGeocoder:(MKReverseGeocoder *)geo didFailWithError:(NSError *)error {
[geocoder release];
geocoder = nil;
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geo didFindPlacemark:(MKPlacemark *)placemark {
**THIS IS WHERE THE ERROR IS OCCURRING** (REQUEST FOR MEMBER 'LOCALITY' IN SOMETHING NOT A STRUCTURE OR UNION)
location = [NSString stringWithFormat:#"%#", placemark.locality];
[geocoder release];
geocoder = nil;
}
I realize that this is a relatively old question, but ...
I ran into the exact same issue and resorted to using the addressDictionary placemark attribute, e.g.,
[placemark.addressDictionary objectForKey#"City"]
instead of
placemark.subAdministrativeArea
I don't understand why the latter doesn't work either.
This error usually occurs when you are trying to access a member of a structure, but in something that is not a structure. For example:
struct {
int a;
int b;
} foo;
int fum;
fum.d = 5;
It also happens if you're trying to access an instance when you have a pointer, and vice versa. For example:
struct foo {
int x, y, z;
};
struct foo a, *b = &a;
b.x = 12; /* This will generate the error, it should be b->x or (*b).x */
It also appears if you do this:
struct foo { int x, int y, int z }foo;
foo.x=12
instead of:
struct foo { int x; int y; int z; }foo;
foo.x=12
Because then, you get a code that looks like it's dealing with instances, when in fact it's dealing with pointers.
It seems to me that you need to check on your code.
Perhaps, try this:
NSString *strLocation = (NSString *)placemark.locality; // Get locality
I know from this forum that this is a known bug that has been reported to Apple, but I am concerned that the memory leak keeps increasing everytime I call the view.
the relevant code is
-(IBAction)getlocationgo:(id) sender{
//NSAutoreleasePool *pool;
//pool = [[NSAutoreleasePool alloc] init];
self.locationManager=[[[CLLocationManager alloc]init]autorelease];
self.locationManager.delegate = self;
[locationManager startUpdatingLocation];
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
//mapView.showsUserLocation =YES;
//[pool release];
}
- (void)locationManager:(CLLocationManager*)aManager didFailWithError:(NSError*)anError
{
switch([anError code])
{
case kCLErrorLocationUnknown: // location is currently unknown, but CL will keep trying
break;
case kCLErrorDenied: // CL access has been denied (eg, user declined location use)
{UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Location Error"
message:#"Please enable Location Services in the Settings menu"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
[alert show];
[alert release];}
break;
case kCLErrorNetwork: // general, network-related error
{UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Location Error"
message:#"The Little Helper can't find you - please check your network connection or that you are not in airplane mode"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
[alert show];
[alert release];}
break;
}
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog(#"thisruns");
MKCoordinateSpan span;
span.latitudeDelta =0.2;
span.longitudeDelta =0.2;
MKCoordinateRegion region;
region.span = span;
region.center = newLocation.coordinate;
[mapView setRegion:region animated:YES];
mapView.showsUserLocation =YES;
mapView.mapType = MKMapTypeHybrid;
latitude.text = [NSString stringWithFormat:#"%f",newLocation.coordinate.latitude];
longitude.text = [NSString stringWithFormat:#"%f",newLocation.coordinate.longitude];
NSString *newloc=longitude.text;
NSLog(#"long%f", newloc);
[locationManager stopUpdatingLocation];
}
the property's are with this
#property (nonatomic, retain) CLLocationManager *locationManager;
and it is dealloced
mapView.delegate = nil;
[mapView release];
locationManager.delegate = nil;
[locationManager release];
I have been going back and forward with this for a few days now, any help or tips would be great.
Thank you
Edit One
Trying to access locationManager in the app delegate, everything runs but there is no update to the location from the IBaction
This is the code in the IBaction and the result from the log is (null)
LLHelperAppDelegate *appDelegate = (LLHelperAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.locationManager startUpdatingLocation];
appDelegate.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
NSLog(#"%#", [appDelegate locationManager]);
Whilst as an Apple issue you won't be able to remove the leak entirely, you can definitely stop it from happening every time you trigger getlocationgo. Rather than constantly creating a CLLocationManager, just use a single CLLocationManager in your app's delegate (or create a singleton to support it). That way you'll only alloc/init a location manager once during your app's lifecycle, whereas currently you alloc/init one every time you reload that view / call the getlocationgo method.
I am trying to create simple GPS application just to display simple data in simulator. I have no errors just cant obtain data. "didFailWithError" method is the only I can get to work :), this is the code:
- (void)viewDidLoad
{
[super viewDidLoad];
lm = [[CLLocationManager alloc] init];
if([CLLocationManager locationServicesEnabled])
{
lm.delegate = self;
lm.desiredAccuracy = kCLLocationAccuracyBest;
//lm.distanceFilter = 1000.0f;
[lm startUpdatingLocation];
}
}
- (void) locationManager: (CLLocationManager *) manager
didUpdateToLocation: (CLLocation *) newLocation
fromLocation: (CLLocation *) oldLocation{
NSString *lat = [[ NSString alloc] initWithFormat:#"%g", newLocation.coordinate.latitude];
txtLatitude.text = lat;
NSString *lng = [[NSString alloc] initWithFormat:#"%g", newLocation.coordinate.longitude];
txtLongitude.text = lng;
NSString *acc = [[NSString alloc] initWithFormat:#"%g", newLocation.horizontalAccuracy];
txtAccuracy.text = acc;
[acc release];
[lat release];
[lng release];
}
- (void) locationManager:(CLLocationManager *)manager
didFailWithError: (NSError *) error
{
NSString *msg = [[NSString alloc] initWithString:#"Error obtaining location"];
UIAlertView *alert = [[ UIAlertView alloc] initWithTitle:#"Error"
message:msg
delegate:nil
cancelButtonTitle:#"Done"
otherButtonTitles:nil];
[alert show];
[msg release];
[alert release];
}
It doesnt move ever in the simulator.
http://developer.apple.com/library/ios/#documentation/Xcode/Conceptual/iphone_development/125-Using_iPhone_Simulator/iphone_simulator_application.html
"Core Location Functionality
The relocation reported by the CoreLocation framework in the simulator is fixed at the following coordinates (accuracy 100 meters), which correspond to 1 Infinite Loop, Cupertino, CA 95014.
Latitude: 37.3317 North
Longitude: 122.0307 West"
You could try adding a simple random or timed event which pings the didUpdate... method explicitly with fake data of your preference.