Get New Location when App Enters Foreground - iphone

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;
}

Related

iPhone Map application ipa crashing on iOS6

My Map application is on iTune market which runs good on iOS 4 and iOS 5. I have developed this application using Xcode 3.2, iPhone sdk 4.2 on Mac mini having Mac OS 10.6.8.
This application .ipa file is crashing after launching on iOS 6. I am developing app on MacMini and I could not able to run xcode 4.5 to rectify the crash. I am pasting some code which runs on launching. If there is some deprecated methods which causes crash then please help because I am not able to check this code without Mac OS 10.7(Lion)..
- (void)viewDidLoad {
if([appDelegate.markers count] == 0 && [mapView.annotations count] == 0 && UserId.data == 0)
{
[self performSelector:#selector(launchActivity) withObject:nil afterDelay:1.0];
}
}
- (void) launchActivity {
Reachability *r = [Reachability reachabilityWithHostName:#"www.google.com"];
NetworkStatus internetStatus = [r currentReachabilityStatus];
if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
{
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:#"No Internet Connectivity!" message:#"This app require an internet connection via WiFi or cellular network to work." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[myAlert show];
[myAlert release];
}
else
{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
if([self.mapView.annotations count] == 1)
{
}
if (locationManager.location == nil)
{
}
else
{
// Change map region using span (degrees)...
MKCoordinateSpan span = MKCoordinateSpanMake(0.001, 0.001);
MKCoordinateRegion region = MKCoordinateRegionMake
(locationManager.location.coordinate, span);
[mapView setRegion:region animated:YES];
}
mapView.showsUserLocation = YES;
BOOL locationAllowed = [CLLocationManager locationServicesEnabled];
if (locationAllowed==NO)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Location Service Disabled"
message:#"To re-enable, please go to Settings and turn on Location Service for this app."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
else
{
[NSThread detachNewThreadSelector:#selector(updateFilterProgress) toTarget:self withObject:nil]; //NSthread not taken because Default.png stay while loading the results
//========================================================================================== ==================================
//Searching Showroom Locations withing the radius
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
appDelegate = (HettichLocatorAppDelegate *)[[UIApplication sharedApplication] delegate];
CLLocationCoordinate2D location;
NSString *url = [[NSString alloc] initWithFormat:#"http://www.company.com.au/directory/phpsqlsearch_genxml.php?lat=%f&lng=%f&radius=5",locationManager.location.coordinate.latitude,locationManager.location.coordinate.longitude];
radiusinurl.text = #"5km";
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];
[parser release];
[xmlParser release];
//[URL release];
[url release];
if(success)
{
annobjs = [[NSMutableArray array] retain];
if([appDelegate.markers count] == 0)
{
//some logic
}
else
{
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 *annobj = [[AddressAnnotation alloc] initWithCoordinate:location];
annobj.title = aMarker.name;
annobj.subtitle = aMarker.address;
[annobjs addObject:annobj];
[mapView addAnnotation:annobj];
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);
mapView.region = ausRegion;
[annobj release];
[_tableView reloadData];
}
}
}
else
{
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:#"" message:#"Unable to find the results." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[myAlert show];
[myAlert release];
}
[pool release];
}
}
}
}

Using a variable declared somewhere else in a different method

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

Application crashing at Loading UIalertview indicator while loading data in iphone

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/

Customized Annotation

i have a question regarding customized annotation here. Here is how i show the pin but i wish to insert an image in to the annotation when the user click on the pin. how can i do that?
- (void) showMarkingOnMap:(Service *) ser
{
if (!self.mapView.loaded) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"iPoly"
message:#"Failed to load the map."
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil, nil];
[alert show];
[alert release];
return;
}
id<AGSLayerView> graphicsLayerView = [self.mapView.mapLayerViews objectForKey:#"GraphicsLayer"];
AGSGraphicsLayer *graphicsLayer = (AGSGraphicsLayer*)graphicsLayerView.agsLayer;
[graphicsLayer removeAllGraphics];
// Create a symbols png graphic
AGSPictureMarkerSymbol *genSymbol = [AGSPictureMarkerSymbol pictureMarkerSymbolWithImageNamed:#"pushpin.png"];
ServiceInfoTemplate *infoTemplate = [[ServiceInfoTemplate alloc] init];
AGSGraphic *genGraphic;
AGSPoint *genPt;
NSMutableDictionary *dic= [[NSMutableDictionary alloc] init];
[dic setObject:[ser name] forKey:#"NAME"];
if([ser.location isEqualToString: #"\n"] || (ser.location == nil)){
[dic setObject:#"" forKey:#"DESC"];
} else {
[dic setObject:[ser location] forKey:#"DESC"];
}
genPt = [AGSPoint pointWithX:[[ser xcoordinate] floatValue]
y:[[ser ycoordinate] floatValue]
spatialReference:self.mapView.spatialReference];
genGraphic = [[AGSGraphic alloc] initWithGeometry:genPt symbol:genSymbol attributes:dic infoTemplateDelegate:infoTemplate];
[graphicsLayer addGraphic:genGraphic];
[graphicsLayer dataChanged];
[self.mapView zoomWithFactor:0.1 atAnchorPoint:genPt.cgPoint animated:NO];
[self.mapView centerAtPoint:genPt animated:YES];
//CGPoint *pt = CGPointMake([[ser ycoordinate] floatValue], [[ser xcoordinate] floatValue]);
}
It's not as easy as you might hope/think. Here's a full tutorial on how to do it.
Note that with this implementation, your callout will occupy the entire width of the view.
See:
http://blog.asolutions.com/2010/09/building-custom-map-annotation-callouts-part-1/

iPhone GPS problem simulator doesn't react

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.