CLGeocoder not working - iphone

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after app launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];
[window addViewForTouchPriority:viewController.view];
if(self.locationManager==nil){
locationManager=[[CLLocationManager alloc] init];
locationManager.delegate=self;
locationManager.purpose = #"We will try to tell you where you are if you get lost";
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
locationManager.distanceFilter=500;
self.locationManager=locationManager;
}
geoCoder = [[CLGeocoder alloc] init];
if([CLLocationManager locationServicesEnabled]){
[self.locationManager startUpdatingLocation];
}
return YES;
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
lati = [[NSString alloc] initWithFormat:#"%+.6f", newLocation.coordinate.latitude];
NSLog(#"address:%#",lati);
longi = [[NSString alloc] initWithFormat:#"%+.6f", newLocation.coordinate.longitude];
NSLog(#"address:%#",longi);
CLLocationCoordinate2D coord;
coord.latitude = [lati doubleValue];
coord.longitude = [longi doubleValue];
[geoCoder reverseGeocodeLocation: newLocation completionHandler: ^(NSArray *placemarks, NSError *error)
{
//Get nearby address
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//String to hold address
NSString *locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
//Print the location to console
NSLog(#"I am currently at %#",locatedAt);
address = [[NSString alloc]initWithString:locatedAt];
NSLog(#"address:%#",address);
}];
}
I am using above code to get address by giving latitude and longitude, but control is not entering in to geocoder method, it skips it. Can anybody help me in it.
Thanks in advance.

It doesn't matter, control does not enter in the method, but it works, note the output it will work.

that is normal, because the code inside the reverseGeocodeLocation is execute inside a block.
The execution of the code inside a block occurs in another thread, so is not execute in the main thread, that's why the control don't enter inside the geocoder method.

Related

CLLocationManager always locates London

I have the following lines of code to locate my position, but I always get the the same location regardless of where I am:
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *location = [locations lastObject];
self.lati = [NSString stringWithFormat:#"%f",location.coordinate.latitude];
self.longi = [NSString stringWithFormat:#"%f",location.coordinate.longitude];
[locationManager stopUpdatingLocation];
locationManager.delegate = nil;
}
in .h write
<CLLocationManagerDelegate>
then this also
CLGeocoder *geocoder;
CLLocationManager *locationManager;
then in .m
locationManager = [[CLLocationManager alloc] init] ;
locationManager.delegate = self;
[CLLocationManager locationServicesEnabled];
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLHeadingFilterNone;
[locationManager startUpdatingLocation];
and then implement its delegates
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation(CLLocation*)newLocation fromLocation:(CLLocation *)oldLocation
{
[manager stopUpdatingLocation];
userCoordinate=newLocation.coordinate;
[[NSUserDefaults standardUserDefaults] setFloat:userCoordinate.latitude
forKey:#"userLat"];
[[NSUserDefaults standardUserDefaults] setFloat:userCoordinate.longitude
forKey:#"userLong"];
CLGeocoder * geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {
for (CLPlacemark * placemark in placemarks)
{
NSString *cityName = #"";
NSString *countryName = #"";
cityName = [placemark.addressDictionary valueForKey:#"City"];
countryName = [placemark.addressDictionary valueForKey:#"Country"];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:cityName forKey:#"CityName"];
[prefs setObject:countryName forKey:#"CountryName"];
}
}];
[manager stopUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
[manager stopUpdatingLocation];
if(error.code == kCLErrorDenied)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"You have to select \"Allow\" for current location." delegate:self cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
alert.tag = 888;
[alert show];
}
[[NSUserDefaults standardUserDefaults] setFloat:0.0
forKey:#"userLat"];
[[NSUserDefaults standardUserDefaults] setFloat:0.0
forKey:#"userLong"];
[manager stopUpdatingLocation];
}
Use this delegate method in place of your delegate method. It will work for you.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
myLatitude = newLocation.coordinate.latitude;
myLongitude = newLocation.coordinate.longitude;
NSLog(#"LAT AND LON IS %f %f",myLatitude,myLongitude);
}

How to get device location name in iPhone?

Currently i am working in iPhone application, Using CLLocationManager to get Latitude and Longitude values fine.
I didn't know this? How to get the device location (Address) name from this latitude and longitude value? please help me
Thanks in Advance
I tried this:
- (void)viewDidLoad
{
[super viewDidLoad];
LocationManager = [[CLLocationManager alloc]init];
LocationManager.delegate=self;
LocationManager.desiredAccuracy = kCLLocationAccuracyBest;
[LocationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSString * latitude = [[[NSString alloc] initWithFormat:#"%f", newLocation.coordinate.latitude]autorelease];
NSString * longitude = [[[NSString alloc] initWithFormat:#"%f", newLocation.coordinate.longitude]autorelease];
[LocationManager stopUpdatingLocation];
NSLog(#"latitude:%#",latitude);
NSLog(#"longitude:%#",longitude);
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
[manager stopUpdatingLocation];
lati = [[NSString alloc] initWithFormat:#"%+.6f", newLocation.coordinate.latitude];
NSLog(#"address:%#",lati);
longi = [[NSString alloc] initWithFormat:#"%+.6f", newLocation.coordinate.longitude];
NSLog(#"address:%#",longi);
[geoCoder reverseGeocodeLocation: newLocation completionHandler: ^(NSArray *placemarks, NSError *error)
{
//Get nearby address
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//String to hold address
NSString *locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
//Print the location to console
NSLog(#"I am currently at %#",locatedAt);
address = [[NSString alloc]initWithString:locatedAt];
NSLog(#"address:%#",address);
}];
}
CLGeocoder *ceo = [[CLGeocoder alloc]init];
CLLocation *loc = [[CLLocation alloc]initWithLatitude:32.00 longitude:21.322];
[ceo reverseGeocodeLocation: loc completionHandler:
^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(#"placemark %#",placemark);
//String to hold address
NSString *locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
NSLog(#"addressDictionary %#", placemark.addressDictionary);
NSLog(#"placemark %#",placemark.region);
NSLog(#"placemark %#",placemark.country); // Give Country Name
NSLog(#"placemark %#",placemark.locality); // Extract the city name
NSLog(#"location %#",placemark.name);
NSLog(#"location %#",placemark.ocean);
NSLog(#"location %#",placemark.postalCode);
NSLog(#"location %#",placemark.subLocality);
NSLog(#"location %#",placemark.location);
//Print the location to console
NSLog(#"I am currently at %#",locatedAt);
}];
You have ta make some reverse location. You're lucky : Apple provides a class to do that.
See CLGeocoder (for iOS >= 5.0) or MKReverseGeocoder (for iOS < 5.0)
You can use Google Maps API for this (works on any iOS):
NSString *req = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?latlng=%.5f,%.5f&sensor=false&language=da", location.latitude, location.longitude];
NSString *resultString = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
Then you can parse this response to NSDictionary using Any JSON library (SBJSON in this case):
SBJSON *jsonObject = [[SBJSON alloc] init];
NSError *error = nil;
NSDictionary *response = [jsonObject objectWithString:resultString error:&error];
[jsonObject release];
Extracting address:
if (error) {
NSLog(#"Error parsing response string to NSObject: %#",[error localizedDescription]);
}else{
NSString *status = [response valueForKey:#"status"];
if ([status isEqualToString:#"OK"]) {
NSArray *results = [response objectForKey:#"results"];
int count = [results count];
//NSSLog(#"Matches: %i", count);
if (count > 0) {
NSDictionary *result = [results objectAtIndex:0];
NSString *address = [result valueForKey:#"formatted_address"];
}
}
}
You have to create a CLLocation object and pass that on to reverseGeoCoder.
Before iOS 5.0 we have MKReverse Geo-coder class to find this..Now it is deprecated..
We have to use CLGeocoder class in Core Location Framework

iPhone SDK MKPlacemark

I need help with the MapKit framework. I am new to iPhone development.
I have a webview that loads from a url with 3 params like this:
in viewDidLoad method from the view controller:
NSString *hoUrlString = [NSString stringWithFormat:#"http://fastenergy.clavis-solutions.de/?iwidth=%#&iheight=%#&zipcode=%#", hString, wString, zipcode];
I can't get the zipcode. I am calling this before the url:
locationController = [[HoCLController alloc] init];
locationController.delegate = self;
[locationController.locationManager startUpdatingLocation];
and in this method from HoCLController.m
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
, I call
MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:coord];
[geocoder setDelegate:self];
[geocoder start];
Then I have these 2 methods
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {
NSLog(#"The geocoder has returned: %#", placemark.postalCode);
}
-(void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
NSLog(#"Error: %#", [error description]);
}
The question is , how can I get the zipcode in the url?
Thank you and please help.
You have already the answer in your question.
placemark.postalcode consists of your zipcode.
Just make sure, that all your variables consist the right value.
zipcode = placemark.postalCode;
Should be the answer, if i get your question right.
MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:coord];
You have to pass coordinate in this method. So check if coord is not nil.I guess this is what you want.
MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate];
Oh Ok, forget it..
I miss something, sorry
Are you subclassing CLLocationManager ???
If not, why are you allocating like this: locationManager = [[HoCLController alloc] init]; instead of this:self.locationManager = [[CLLocationManager alloc] init]; I'm sorry if I'm getting something wrong, but think i'm giving you the answer..

Core Location returning 00

Here's the full method, I didn't put the second half originally because I know it works:
-(void)showDirections
{
locationManager = [[CLLocationManager alloc] init];
[locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
[locationManager setDelegate:self];
CLLocation *location = [locationManager location];
CLLocationCoordinate2D coordinate = [location coordinate];
NSNumber *myLatitude = [NSNumber numberWithDouble:coordinate.latitude];
NSNumber *myLongitude = [NSNumber numberWithDouble:coordinate.longitude];
double myLatitude2 = [myLatitude doubleValue];
double myLongitude2 = [myLongitude doubleValue];
NSArray *array = [dataHold objectForKey:#"Subtree"];
NSString *latitude = [NSString stringWithFormat:#"%#",[array objectAtIndex:4]];
NSString *longitude = [NSString stringWithFormat:#"%#",[array objectAtIndex:5]];
double clubLatitude = [latitude doubleValue];
double clubLongitude = [longitude doubleValue];
CLLocationCoordinate2D start = { myLatitude2, myLongitude2};
CLLocationCoordinate2D destination = { clubLatitude, clubLongitude};
NSString *googleMapsURLString = [NSString stringWithFormat:#"http://maps.google.com/?saddr=%1.6f,%1.6f&daddr=%1.6f,%1.6f",start.latitude, start.longitude, destination.latitude, destination.longitude];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:googleMapsURLString]];
}
Two issues:
1) You are doing a NSNumber box/unbox cycle that has no use whatsoever
2) Core Location is asynchronous, therefore you cannot return the user's location straight away, you must use the delegate method(s) to retrieve the location if/when it is available.
Here's an example of how it should work:
-(void)showDirections
{
locationManager = [[CLLocationManager alloc] init];
[locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
[locationManager setDelegate:self];
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocationCoordinate2D coord = [newLocation coordinate];
NSArray *array = [dataHold objectForKey:#"Subtree"];
NSString *latitude = [NSString stringWithFormat:#"%#",[array objectAtIndex:4]];
NSString *longitude = [NSString stringWithFormat:#"%#",[array objectAtIndex:5]];
double clubLatitude = [latitude doubleValue];
double clubLongitude = [longitude doubleValue];
NSString *googleMapsURLString = [NSString stringWithFormat:#"http://maps.google.com/?saddr=%1.6f,%1.6f&daddr=%1.6f,%1.6f", coord.latitude, coord.longitude, clubLatitude, clubLongitude];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:googleMapsURLString]];
}
The fourth line of your code is where the problem begins. You cannot get the location instantly, you will need to wait until the location services notify the delegate that a location is available. I will add some comments to your code to explain:
-(void)showDirections
{
locationManager = [[CLLocationManager alloc] init];
[locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
[locationManager setDelegate:self];
// this is not where you should be looking
CLLocation *location = [locationManager location];
// the rest of this function is not included in this example ...
}
Since you set the delegate as "self", the current class but implement the "CLLocationManagerDelegate" protocol, which defines the following two functions:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { /* */ }
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { /* */ }
That is where you will get a location provided to you.
Dont forget to update your class definition like so:
#interface MyClass : NSObject <CLLocationManagerDelegate> {
And as a side note, it seems like you do not fully understand delegates and the purpose that they serve, which is fine if you are new to Objective-C, but getting more familiar with them will certainly make your life a bit easier.
Some other helpful stuff:
A CoreLocation Tutorial (covers what you are trying to do)

CLLocationDistance: Cant get "getDistanceFrom" to work

view based app,
.m
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self;
[[self locationManager] startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
CurrentLocation = newLocation;
[locationManager stopUpdatingLocation];
myActivity.hidden=YES;
[self reStart];
}
-(void)reStart{
[self checkAndCreateDatabase]; //Sucess
[self readFromDatabase]; //Success if I comment the get distance part
[self sort]; //Success
}
-(void) readFromDatabase {
...
CLLocationCoordinate2D cord;
cord.latitude = [[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)] doubleValue];
cord.longitude =[[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)] doubleValue];
NSDate *today = [NSDate date];
CLLocation *objectLocation = [[CLLocation alloc] initWithCoordinate:cord altitude:1 horizontalAccuracy:1 verticalAccuracy:-1 timestamp:today];
CLLocationDistance distance = [objectLocation getDistanceFrom:CurrentLocation]/1000;
NSLog([NSString stringWithFormat:#"%.0f", distance]);
}
What is wrong?
debugger says:
obj_msgSend
0x912e8688 <+0024> mov 0x20(%edx),%edi
object from database:
long: 59.291114
lat: 17.816191
Use distanceFromLocation: instead
Is CurrentLocation an instance-variable/property? You are setting it directly without an accessor and you are not retaining it. If it is released before you use it in getDistance: it will cause a crash.
If it is a property use the self.CurrentLocation to ensure it is retained.
Also, the construction...
NSLog([NSString stringWithFormat:#"%.0f", distance]);
... is risky and redundant. Use...
NSLog(#"%.0f", distance);
... instead.