unexpected results from geocodeAddressString - ios7

My question is, why are poiCoordinate's latitude and longitude properties coming out 0, 0 when addressTF.text has a very sensible address string, for example "1 Infinite Loop, Cupertino, CA 95014"?
//HomeViewController.m
#implementation HomeViewController
CLLocationCoordinate2D poiCoordinate;
-(void)performStringGeocode
{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:_addressTF.text completionHandler:^(NSArray *placemarks, NSError *error)
{
if (error)
{
NSLog(#"Geocode failed with error: %#", error);
return;
}
CLPlacemark *placemark = [placemarks firstObject]; //Line A
poiCoordinate = placemark.location.coordinate; //Line B
}];
}

Related

Retrieving resultant data from blocks

-(void) ReverseGeocode
{
CLGeocoder *geocoder=[[CLGeocoder alloc]init];
[geocoder reverseGeocodeLocation:self.toLocation
completionHandler:^(NSArray *placemarks, NSError *error){
if(error){
NSLog(#"Geocode failed with error: %#",error);
return;
}
if(placemarks &&placemarks.count>0){
CLPlacemark *placemark=placemarks[0];
NSDictionary *addressDictionary=placemark.addressDictionary;
NSString *Address=[addressDictionary objectForKey:(NSString*)
kABPersonAddressStreetKey];
NSString *City=[addressDictionary objectForKey:(NSString*)
kABPersonAddressCityKey];
NSString *State=[addressDictionary objectForKey:(NSString*)
kABPersonAddressStateKey];
NSString *Zip=[addressDictionary objectForKey:(NSString*)
kABPersonAddressZIPKey];
NSString *adress=[NSString localizedStringWithFormat:#"%# %# %# %# %#",
Address,City,State,#"United States",Zip];
// return adress;
}
}];
}
Above is a method for ReverseGeocoding.
I am trying to retrieve the final result, NSString adress. How can I do that. I have many such methods where I need to retrieve the data.
- (void)reverseGeocodeWithCompletionHandler:(void (^)(NSString *address))completionHandler {
[geocoder reverseGeocodeLocation:self.toLocation
completionHandler:^(NSArray *placemarks, NSError *error){
if(error) {
NSLog(#"Geocode failed with error: %#",error);
completionHandler(nil);
} else if {
if(placemarks &&placemarks.count>0) {
//...
NSString *adress=[NSString localizedStringWithFormat:#"%# %# %# %# %#",
Address,City,State,#"United States",Zip];
completionHandler(address);
}
}];
}
Call this method like this:
[obj reverseGeocodeWithCompletionHandler:^(NSString *address) {
NSLog(#"Address is = %#", address);
}];

Can't reverse geolocate using lat/long - throws type errors

I am able to get the user latitude and longitude and display them correctly in the console log... but I can't reverse geolocate to a city name or anything with them.
What am I doing wrong?
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *userlatitude = [locations lastObject];
CLLocation *userlongitude = [locations objectAtIndex:locations.count-2];
CLGeocoder *ceo = [[CLGeocoder alloc]init];
CLLocation *loc = [[CLLocation alloc]initWithLatitude:userlatitude longitude:userlongitude];
[ceo reverseGeocodeLocation: loc completionHandler: ^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSString *locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
NSLog(#"Currently located at %#",locatedAt);
}];
[locationManager stopUpdatingLocation];
}
I have also tried replacing CLLocation *userlatitude .... objectAtIndex:location.count-2]; with
CLLocationDegrees userlatitude = [[locations lastObject] doubleValue];
CLLocationDegrees userlongitude = [[locations objectAtIndex:locations.count-2] doubleValue];
but this returns an error during runtime (even though it does not show any syntax errors in the code editor).
didUpdateLocations method returns a array of CLLocation objects containing the location data. This array always contains at least one object representing the current location.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLGeocoder *ceo = [[CLGeocoder alloc]init];
[ceo reverseGeocodeLocation:(CLLocation *)[locations lastObject] // pass the most recent value
completionHandler: ^(NSArray *placemarks, NSError *error) {
if (error) {
NSLog(#"reverse error: %#", error);
// handle error here
return;
}
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSString *locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"]
componentsJoinedByString:#", "];
NSLog(#"Currently located at %#",locatedAt);
}];
}

What is wrong with this locking scheme

for (NSString * district in allLinedStrings) {
PO1(district);
[self.mainLock lock];
CLGeocoder * geocode= [[CLGeocoder alloc]init];
[geocode geocodeAddressString:district completionHandler:^(NSArray *placemarks, NSError *error )
{
for (CLPlacemark * thePlace in placemarks)
{
[self handlePlacemark:thePlace];
}
[self.mainLock unlock];
}];
}
I want to run geocodeAddressString synchronously and I do this. Somehow I got error of deadlock. But what's wrong?
If you are using NSLock: Calling the lock method twice on the same thread will lock up your thread permanently.
for (NSString * district in allLinedStrings) {
PO1(district);
[self.mainLock lock];
CLGeocoder * geocode= [[CLGeocoder alloc]init];
[geocode geocodeAddressString:district completionHandler:^(NSArray *placemarks, NSError *error )
{
for (CLPlacemark * thePlace in placemarks)
{
[self handlePlacemark:thePlace];
}
}];
[self.mainLock unlock];
}

Coordinates/Region from Country Name

How can I extract a CLRegion or CLLocationCoordinate2D or latitude/longitude points based on a correctly written country name? Would CLGeocoder work like this:
CLGeocoder *geoCode = [[CLGeocoder alloc] init];
[geoCode geocodeAddressString:#"Singapore" completionHandler:^(NSArray *placemarks, NSError *error) {
if (!error) {
CLPlacemark *place = [placemarks objectAtIndex:0];
NSLog(#"%i,%i", place.//what would i put here);
}
}];
What variable does a CLPlacemark hold that tells the address?
Never mind figured it out:
CLGeocoder *geoCode = [[CLGeocoder alloc] init];
[geoCode geocodeAddressString:#"Singapore" completionHandler:^(NSArray *placemarks, NSError *error) {
if (!error) {
CLPlacemark *place = [placemarks objectAtIndex:0];
CLLocation *location = place.location;
CLLocationCoordinate2D coord = location.coordinate;
NSLog(#"%g is latitude and %g is longtitude", coord.latitude, coord.longitude);
}
}];

Altering values within blocks in Objective - C

I have a block of code that adds an object to an array declared outside the block with the "__block" notation (it's an ivar). However, once the block is exited, the array contains no values. I know that it isn't trying to add empty strings to the array, because my console prints the strings correctly. Any help would be appreciated. Here is my code:
addressOutputArray = [[NSMutableArray alloc] init];
for(CLLocation *location in locationOutputArray)
{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error)
{
if(placemarks && placemarks.count > 0)
{
CLPlacemark *topResult = [placemarks objectAtIndex:0];
NSString *address = [NSString stringWithFormat:#"%# %#,%# %#", [topResult subThoroughfare],[topResult thoroughfare],[topResult locality], [topResult administrativeArea]];
[addressOutputArray addObject:address];
NSLog(#"%#",address);
}
}];
[geocoder release];
}
NSLog(#"Address output array count: %d", [addressOutputArray count]);
The final log gives me a count of zero. Any help at all would be really appreciated.
The problem is that reverseGeocodeLocation executes asynchronously, and you are not waiting for the calls to complete before logging the size of your output array. You might have better luck with something like:
for(CLLocation *location in locationOutputArray)
{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error)
{
if(placemarks && placemarks.count > 0)
{
CLPlacemark *topResult = [placemarks objectAtIndex:0];
NSString *address = [NSString stringWithFormat:#"%# %#,%# %#", [topResult subThoroughfare],[topResult thoroughfare],[topResult locality], [topResult administrativeArea]];
[addressOutputArray addObject:address];
NSLog(#"%#",address);
NSLog(#"Address output array count is now: %d", [addressOutputArray count]);
}
}];
[geocoder release];
}
In any case, you are doing everything correctly with your block in terms of how you are setting it up and using it to modify the state of your addressOutputArray ivar. The only problem is that you were not waiting until all your blocks had finished executing before checking the result.