Not getting current user location - iphone

in .h file
#import <MapKit/MapKit.h>
#interface FirstViewController : UIViewController <MKMapViewDelegate,MKReverseGeocoderDelegate,CLLocationManagerDelegate>
{
}
in .m file
-(void)viewDidLoad
{
CLLocationManager *locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
[super viewDidLoad];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
MKReverseGeocoder *geoCoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate];
geoCoder.delegate = self;
[geoCoder start];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"locationManager:%# didFailWithError:%#", manager, error);
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
MKPlacemark * myPlacemark = placemark;
NSString *kABPersonAddressCityKey;
NSString *city = [myPlacemark.addressDictionary objectForKey:(NSString*) kABPersonAddressCityKey];
lblAddress.text = city;
NSLog(#"city detail is:--> %#",city);
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error
{
NSLog(#"reverseGeocoder:%# didFailWithError:%#", geocoder, error);
}
This is the code which I have done to get the current location of user & print it in the label.
But the CLLocationManager delegate method (which are written above) is not called & I am not able to get the current address.
Please help me out.
Where I am doing mistake...? guide me.
Thanks.

Instead of autoreleasing the CLLocationManager instance, assign it to an ivar in your class. Then release it in -dealloc as usual (or in one of the delegate methods if you don't need it any longer).
I suspect your location manager is getting deallocated on the next turn of the run loop before having an opportunity to fire off its delegate methods.

In your method viewDidLoad:
-(void)viewDidLoad
{
CLLocationManager *locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
myMapView.showsUserLocation = YES; // add this line
[super viewDidLoad];
}
And you are done!!!

Related

Get current location using CLLocationCoordinate2D

I am trying to get current location of user using CLLocationCoordinate2D. I want the values in the format like
CLLocationCoordinate2D start = {-28.078694,153.382844 };
So that I can use them like following:
NSString *urlAddress = [NSString
stringWithFormat:#"http://maps.google.com/?saddr=%1.6f,%1.6f&daddr=%1.6f,%1.6f",
start.latitude, start.longitude,
destination.latitude, destination.longitude];
I used
CLLocation *location = [[CLLocation alloc]init ];
CLLocationDegrees currentLatitude = location.coordinate.latitude;
CLLocationDegrees currentLongitude = location.coordinate.longitude;
to get current lat & long.
But I am getting 0.000 for both when I try to test. I am testing on iPhone 4s.
If there is any sample code, it will be great.
Add CoreLocation framework first and then use the following code...and your viewController must implement CLLocationManagerDelegate
-(void)findCurrentLocation
{
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
if ([locationManager locationServicesEnabled])
{
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
}
CLLocation *location = [locationManager location];
CLLocationCoordinate2D coordinate = [location coordinate];
NSString *str=[[NSString alloc] initWithFormat:#" latitude:%f longitude:%f",coordinate.latitude,coordinate.longitude];
NSLog(#"%#",str);
}
in AppDelegate.h declare following variable. and implement
CLLocationManagerDelegate delegate.
CLLocationManager *locationManager;
CLLocation *currentLocation;
in AppDelegate.h.m file write following code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
self.currentLocation = newLocation;
self.currentLat = newLocation.coordinate.latitude;
self.currentLong = newLocation.coordinate.longitude;
}
You need to use CLLocationManager to get a user's location. CLLocation is only a class of objects used to represent locations, it can't get user location by it self.
For more details and example, please follow to Apple docs on Location Awareness Programming.
CLLocationCoordinate2D location = [[[mapview userLocation] location] coordinate];
NSLog(#"Location found from Map: %f %f",location.latitude,location.longitude);
and also refer the link(without mapview0
https://developer.apple.com/library/ios/#samplecode/LocateMe/Introduction/Intro.html
use location manager to get lat and long, follow this tutorial for sample code http://www.edumobile.org/iphone/miscellaneous/how-to-get-current-latitude-and-longitude-in-iphone/
-(void)findCurrentLocation
{
if ([CLLocationManager locationServicesEnabled])
{
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
[self setLocation:[[manager location] coordinate]];
}

How to update location only when button is pressed

How can I make my application update location only when a button is pressed?
I have a button named "REFRESH". Everytime this button is pressed, I want to show my user their location. For example, 51 Bourke Street, Victoria.
However, I do not want to update my location regularly. I want to update its location only when the button is pressed, to save battery power.
What do you think? Am I doing it correctly?
I have these classes:
VoteViewController.h and VoteViewController.m
CoreLocationController.h and CoreLocationController.m
This is what I have:
VoteViewController.h class
#interface VoteViewController : UIViewController <CoreLocationControllerDelegate>
{
CoreLocationController *coreController;
}
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
- (void)geoReverseAddress:(MKPlacemark *)placeMark;
- (IBAction)refreshButtonPressed;
VoteViewController.m class
- (void)viewDidLoad
{
[super viewDidLoad];
coreController = [[CoreLocationController alloc] init];
coreController.delegate = self;
}
- (IBAction)refreshButtonPressed
{
NSLog(#"Refresh Button pressed");
label.text = [NSString stringWithString:#""];
[coreController.locationManager startUpdatingLocation];
}
- (void)locationUpdate:(CLLocation *)location
{
comments.text = [location description];
[coreController.locationManager stopUpdatingLocation];
}
- (void)locationError:(NSError *)error
{
comments.text = [error description];
[coreController.locationManager stopUpdatingLocation];
}
- (void)geoReverseAddress:(MKPlacemark *)placeMark
{
label.text = [NSString stringWithFormat:#"%# %#, %#", [placeMark subThoroughfare],
[placeMark thoroughfare], [placeMark locality]];
}
CoreLocationController.h class
#protocol CoreLocationControllerDelegate <NSObject>
#required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
- (void)geoReverseAddress:(MKPlacemark *)placeMark;
#end
#interface CoreLocationController : NSObject <CLLocationManagerDelegate, MKReverseGeocoderDelegate>
{
CLLocationManager *locationManager;
id delegate;
MKReverseGeocoder *reverse;
}
#property(nonatomic, retain) CLLocationManager *locationManager;
#property(nonatomic, retain) id delegate;
#end
CoreLocationController.m class
-(id) init
{
self = [super init];
if (self != nil)
{
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self;
self.locationManager.distanceFilter = kCLHeadingFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"Update location");
[self.delegate locationUpdate:newLocation];
reverse = [[MKReverseGeocoder alloc] initWithCoordinate:[newLocation coordinate]];
reverse.delegate = self;
[reverse start];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
[self.delegate locationError:error];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error
{
[self.delegate locationError:error];
[reverse cancel];
[reverse release];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
[self.delegate geoReverseAddress:placemark];
[reverse cancel];
[reverse release];
}
When you first fire up CLLocationManager, you're very likely to get one stale location from the last time it ran. Once that's out of the way, you're going to start getting very inaccurate locations while the device uses WiFi sniffing and cell triangulation, while the GPS looks for a fix.
So in your didUpdateToLocation method, you probably want to throw away the first hit, and then test the .horizontalAccuracy value of your newLocation object for a low enough value to trust.
Apart from that, I don't see anything bad about what you've sent here. I'm not sure I'd go to the trouble of wrapping the location fetching work in its own class, I'd probably just do that out in my viewController. But that's a style choice. If you're reusing this functionality elsewhere, what you've got here is obviously the way to go.

How to get locationManager startMonitoringSignificantLocationChanges accurate readings

Hi I have a requirement where I need to update user's location to the server while app is running in the background. I have used the code below to test it in the car and have found few discrepancies in the lat and long that are reported when the - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation: is fired.The coordinates are way far of to where I actually am at that moment.
I know the didupdatelocation uses cell tower readings hence not very accurate.I was wondering if there is anyway I can start [locationManager startUpdatingLocation] when the - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:; and then get the readings which are much more accurate.
Please any help or directions would be great and highly appreciated.
#import "LocationsAppDelegate.h"
#import "RootViewController.h"
#implementation LocationsAppDelegate
#synthesize window;
#synthesize navigationController;
-(void)initLocationManager {
if (locationManager == nil) {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; // 100 m
// [locationManager startUpdatingLocation];
[locationManager startMonitoringSignificantLocationChanges];
}
}
- (void)saveCurrentData:(NSString *)newData {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *savedData = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:#"kLocationData"]];
[savedData addObject:newData];
[defaults setObject:savedData forKey:#"kLocationData"];
[savedData release];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSDate* eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
//check if the data is less than 15 sec ago
if (abs(howRecent) > 15.0)
{
NSLog(#"old data latitude %+.6f, longitude %+.6f\n",
newLocation.coordinate.latitude,newLocation.coordinate.longitude);
}else{
[locationManager startUpdatingLocation];
NSDateFormatter * formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setTimeStyle:NSDateFormatterMediumStyle];
NSString *locationData = [NSString stringWithFormat:#"%.6f, %.6f, %#",newLocation.coordinate.latitude, newLocation.coordinate.longitude,[formatter stringFromDate:newLocation.timestamp]];
[self saveCurrentData:locationData];
[locationManager stopUpdatingLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSString *errorData = [NSString stringWithFormat:#"%#",[error localizedDescription]];
NSLog(#"%#", errorData);
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (![CLLocationManager significantLocationChangeMonitoringAvailable]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Sorry" message:#"Your device won't support the significant location change." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
return YES;
}
[self initLocationManager];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
- (void)dealloc {
[locationManager release];
[navigationController release];
[window release];
[super dealloc];
}
#end
The behaviour of startMonitoringSignificantLocationChanges is not affected by the distanceFilter or desiredAccuracy properties.
So if you want to retrieve more accurated results, call startUpdatingLocation, and by playing with the distanceFilter and desiredAccuracy properties (kCLLocationAccuracyBestForNavigation, kCLLocationAccuracyBest) are the most accurated, but consumes more power, so play with them.
I didn't understand exactly the behaviour of your code. Why you call startMonitoringSignificantLocationChanges instead of startUpdatingLocation, but you call it inside the delegate method?

How do I get the current location from the location manager?

i want my app to get the exact location (longitude and latitude) of where he is as every second, it is possible ? i have this code so far, every 3 second the app get the current location but it doesnt update if i move...
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
NSLog(#"lol");
[locationManager stopUpdatingLocation];
if (wtf == 2) {
[[NSUserDefaults standardUserDefaults] setObject:newLocation forKey:#"old"];
NSLog(#"wtf");
wtf =0;
}
oldLocation = [[NSUserDefaults standardUserDefaults] objectForKey:#"old"];
double rep = [oldLocation distanceFromLocation:newLocation];
NSString *label1 = [NSString stringWithFormat:#"%2.90f",oldLocation.coordinate.latitude];
NSString *label2 = [NSString stringWithFormat:#"%2.90f",newLocation.coordinate.latitude];
if ([label1 isEqual:label2]) {
NSLog(#"penis");
}
labelm.text = label1;
labelkm.text = label2;
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
}
-(void)actualise{
[locationManager startUpdatingLocation];
}
- (void)viewDidLoad {
[super viewDidLoad];
wtf = 2;
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
[NSTimer scheduledTimerWithTimeInterval:3 target:self selector:#selector(actualise) userInfo:nil repeats:YES];
}
/*
Use this code to initialize and start the location manager:
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
And implement didUpdateToLocation like this:
- (void) locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*) oldLocation
{
// This will be called every time the device has any new location information.
}
There is no need to use any timers.

cllocation and mkreversegeocoder

i'm try to retreiving city name with cllocation and mkreversegeocoder.
in my viewdidload method i istance cllocationmanager:
self.locManager = [[CLLocationManager alloc] init];
locManager.delegate = self;
locManager.desiredAccuracy = kCLLocationAccuracyBest;
[locManager startUpdatingLocation];
and after:
- (void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation
*)newLocation
fromLocation:(CLLocation *)oldLocation {
//some code to retrieve my information
MKReverseGeocoder *geoCoder = [[MKReverseGeocoder alloc]
initWithCoordinate:newLocation.coordinate ];
geoCoder.delegate = self;
[geoCoder start];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark
*)placemark
{
MKPlacemark *myPlacemark = placemark;
citta.text = [placemark locality];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error{
citta.text =# "Unknow";
Application works only the first time i get my value. on the second time app crash.
I think is because geocoder is started and i think i must have one and only one istance running. (but i'm really not shure of this...). in which way i can controll geocoder is running?
I've see that i can istance mkreversegeocoder in my viewdidload using cllocationcoordinate2d but ... in which way i can retreive newlocation.coordinate?
I've partially resolve declaring geocoder as class variable and checking
if (self.geocoder != nil) {
[geocoder release];
}
but.... if in my
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark
*)placemark
or in my
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailedWithError:(#NSError
*)error
i release or cancel my object?
I'm feeling so stupid :D
Don't create the reverse geocoder as a local variable.
Look at the MKReverseGeocoder example in the CurrentAddress sample app provided by Apple. See MapViewController.h and MapViewController.m.
Follow the same pattern in your code.