I am run in my application for finding a current location but first time return right lat long with there dependent locality but when they didUpdateLocations that time goes to didFailWithError and return Domain=kCLErrorDomain Code=0 "(null)". I have try diffrent diffrent solution like
Reset Content and Settings
In Xcode,Product -> Scheme -> Edit
Scheme,then cancel the "Allow Location Simulator"and To the iOS
Simulator and reset Content and Setting and Again to the
Xcode,repeat the first step.and To the iOS Simulator and reset.
but none of that work
my code for this is here:
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations{
NSLog(#"didUpdateToLocation: %#", [locations lastObject]);
CLLocation *currentLocation = [locations lastObject];
if (currentLocation != nil)
{
self.lblLongitude.text = [NSString stringWithFormat:#"%.12f", currentLocation.coordinate.longitude];
self.lblLatitude.text = [NSString stringWithFormat:#"%.12f", currentLocation.coordinate.latitude];
}
NSLog(#"Resolving the Address");
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(#"Found placemarks: %#, error: %#", placemarks, error);
if (error == nil && [placemarks count] > 0) {
placemark = [placemarks lastObject];
NSString *geoMapItem = placemark.description;
NSRange start = [geoMapItem rangeOfString:#"dependentLocality"];
NSRange end = [geoMapItem rangeOfString:#")" options:NSCaseInsensitiveSearch range:NSMakeRange(start.location, 1000)];
NSString *dataString = [geoMapItem substringWithRange:NSMakeRange(start.location, end.location - start.location + end.length)];
dataString = [dataString stringByReplacingOccurrencesOfString:#"\n" withString:#""];
dataString = [dataString stringByReplacingOccurrencesOfString:#" " withString:#""];
dataString = [dataString stringByReplacingOccurrencesOfString:#"\"" withString:#""];
start = [dataString rangeOfString:#"("];
end = [dataString rangeOfString:#")"];
NSLog(#"datastring===>%#",dataString);
lblAddress.text = [NSString stringWithFormat:#"%# \n%# %#\n%#\n%#",
dataString,
placemark.postalCode, placemark.locality,
placemark.administrativeArea,
placemark.country];
} else
{
NSLog(#"%#", error.debugDescription);
}
} ];}
after update location first time goes to error block
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(#"didFailWithError%#",error);
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle:#"Error" message:#"Failed to Get Your Location" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];}
and get this error didFailWithErrorError Domain=kCLErrorDomain Code=0 "(null)"
hello Guys I found The Solutions of My own question.
Some minor mistake done by me. I am check currentLocation != nil every time so, it's update location but current location Lat Long is not set.
//if (currentLocation != nil)
//{
self.lblLongitude.text = [NSString stringWithFormat:#"%.12f", currentLocation.coordinate.longitude];
self.lblLatitude.text = [NSString stringWithFormat:#"%.12f", currentLocation.coordinate.latitude];
//}
now it's Run Properly.
I am using reverse geocoding which works but I am trying to separate the attributes. For example I want to have zip code displayed in it's own text field.
This is what I've tried but I get a breakpoint at if([placemarks count] >0)
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// Make sure this is a recent location event
CLLocation *newLocation = [locations lastObject];
NSTimeInterval eventInterval = [newLocation.timestamp timeIntervalSinceNow];
if(abs(eventInterval) < 30.0)
{
// Make sure the event is valid
if (newLocation.horizontalAccuracy < 0)
return;
// Instantiate _geoCoder if it has not been already
if (_geocoder == nil)
_geocoder = [[CLGeocoder alloc] init];
//Only one geocoding instance per action
//so stop any previous geocoding actions before starting this one
if([_geocoder isGeocoding])
[_geocoder cancelGeocode];
[_geocoder reverseGeocodeLocation: newLocation
completionHandler: ^(NSArray* placemarks, NSError* error)
{
if([placemarks count] > 0)
{
CLPlacemark *foundPlacemark = [placemarks objectAtIndex:0];
self.address.text =
[NSString stringWithFormat:#"%#",
foundPlacemark.description];
self.zip.text =
[NSString stringWithFormat:#"%#",
foundPlacemark.postalCode];
}
else if (error.code == kCLErrorGeocodeCanceled)
{
NSLog(#"Geocoding cancelled");
}
else if (error.code == kCLErrorGeocodeFoundNoResult)
{
self.address.text=#"No geocode result found";
}
else if (error.code == kCLErrorGeocodeFoundPartialResult)
{
self.address.text=#"Partial geocode result";
}
else
{
self.address.text =
[NSString stringWithFormat:#"Unknown error: %#",
error.description];
}
}
];
Try to handle error first by checking if its nil:
if (error) {
// handle here
NSLog(#"error: %#", error);
return; // exit statement
}
// handle code here if there was no error
and avoid strong reference cycles create a weak object of your self, when calling a object use this instnace.
__weak typeof(self) weakSelf = self;
so self.address.text=#"Partial geocode result"; will turn to weakSelf.address.text=#"some text here...";
I have an app that fills in the user location into a textfield, if the user allows location sharing. Everything works but my question is how do I get the results to be split up into multiple text fields.
Currently the "address" text field displays everything. All I want in that field is the street address, and another one for City, State, Zip, etc. Any suggestions would be appreciated! I've looked at the documentation for example for zip code I've tried
self.zip.text=
NSString *postalCode = [NSString stringWithFormat:#"%#",placemark.postalCode];
but that doesn't work
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
if(error.code == kCLErrorDenied)
{
self.address.text = #"Location information denied";
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// Make sure this is a recent location event
CLLocation *newLocation = [locations lastObject];
NSTimeInterval eventInterval = [newLocation.timestamp timeIntervalSinceNow];
if(abs(eventInterval) < 30.0)
{
// Make sure the event is valid
if (newLocation.horizontalAccuracy < 0)
return;
// Instantiate _geoCoder if it has not been already
if (_geocoder == nil)
_geocoder = [[CLGeocoder alloc] init];
//Only one geocoding instance per action
//so stop any previous geocoding actions before starting this one
if([_geocoder isGeocoding])
[_geocoder cancelGeocode];
[_geocoder reverseGeocodeLocation: newLocation
completionHandler: ^(NSArray* placemarks, NSError* error)
{
if([placemarks count] > 0)
{
CLPlacemark *foundPlacemark = [placemarks objectAtIndex:0];
self.address.text =
[NSString stringWithFormat:#"%#",
foundPlacemark.description];
}
else if (error.code == kCLErrorGeocodeCanceled)
{
NSLog(#"Geocoding cancelled");
}
else if (error.code == kCLErrorGeocodeFoundNoResult)
{
self.address.text=#"No geocode result found";
}
else if (error.code == kCLErrorGeocodeFoundPartialResult)
{
self.address.text=#"Partial geocode result";
}
else
{
self.address.text =
[NSString stringWithFormat:#"Unknown error: %#",
error.description];
}
}
];
//Stop updating location until they click the button again
[manager stopUpdatingLocation];
}
}
You should check the reference page for CLPlacemark class.
There you will find the properties you need: postal code, locality ...
CLPlacemark *foundPlacemark = [placemarks lastObject];
NSString *subThoroughfare = [NSString stringWithFormat:#"%#",placemark.subThoroughfare];
NSString *thoroughfare = [NSString stringWithFormat:#"%#",placemark.thoroughfare];
NSString *postalCode = [NSString stringWithFormat:#"%#",placemark.postalCode];
NSString *country = [NSString stringWithFormat:#"%#",placemark.country];
NSString *locality = [NSString stringWithFormat:#"%#",placemark.locality];
NSString *administrativeArea = [NSString stringWithFormat:#"%#",placemark.administrativeArea];
I got the current location based on the Longitude and Latitude values and then I also got multiple places on google map using Annotation. Now I want to get the longitude and latitude values based on the Address( i.e street,city and county).Need some guidance on how this can be achieved.
Till now, this is what I have tried:-
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize streetField = _streetField, cityField = _cityField, countryField = _countryField, fetchCoordinatesButton = _fetchCoordinatesButton, nameLabel = _nameLabel, coordinatesLabel = _coordinatesLabel;
#synthesize geocoder = _geocoder;
- (void)viewDidLoad
{
[super viewDidLoad];
_streetField.delegate=self;
_cityField.delegate=self;
_countryField.delegate=self;
// Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)fetchCoordinates:(id)sender {
NSLog(#"Fetch Coordinates");
if (!self.geocoder) {
NSLog(#"Geocdoing");
self.geocoder = [[CLGeocoder alloc] init];
}
NSString *address = [NSString stringWithFormat:#"%# %# %#", self.streetField.text, self.cityField.text, self.countryField.text];
NSLog(#"GET Addres%#",address);
self.fetchCoordinatesButton.enabled = NO;
[self.geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(#"Fetch Gecodingaddress");
if ([placemarks count] > 0) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(#"GET placemark%#",placemark);
CLLocation *location = placemark.location;
NSLog(#"GET location%#",location);
CLLocationCoordinate2D coordinate = location.coordinate;
self.coordinatesLabel.text = [NSString stringWithFormat:#"%f, %f", coordinate.latitude, coordinate.longitude];
NSLog(#"CoordinatesLabel%#",self.coordinatesLabel.text);
if ([placemark.areasOfInterest count] > 0) {
NSString *areaOfInterest = [placemark.areasOfInterest objectAtIndex:0];
self.nameLabel.text = areaOfInterest;
NSLog(#"NameLabe%#",self.nameLabel.text);
}
}
self.fetchCoordinatesButton.enabled = YES;
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
#end
Above code is not working to give me the latitude and longitude.Need some help on what am I doing wrong here or if I am missing on something.
Thanks in Advance.
This was very old answer, Kindly check with new Updates
EDIT:
Before using this check with iOS8 updation
NSLocationAlwaysUsageDescription
NSLocationWhenInUseUsageDescription
This is for getting lat and long based user area like street name,state name,country.
-(CLLocationCoordinate2D) getLocationFromAddressString: (NSString*) addressStr {
double latitude = 0, longitude = 0;
NSString *esc_addr = [addressStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
if (result) {
NSScanner *scanner = [NSScanner scannerWithString:result];
if ([scanner scanUpToString:#"\"lat\" :" intoString:nil] && [scanner scanString:#"\"lat\" :" intoString:nil]) {
[scanner scanDouble:&latitude];
if ([scanner scanUpToString:#"\"lng\" :" intoString:nil] && [scanner scanString:#"\"lng\" :" intoString:nil]) {
[scanner scanDouble:&longitude];
}
}
}
CLLocationCoordinate2D center;
center.latitude=latitude;
center.longitude = longitude;
NSLog(#"View Controller get Location Logitute : %f",center.latitude);
NSLog(#"View Controller get Location Latitute : %f",center.longitude);
return center;
}
call the method like this in viewdidload method or somewhere according to your project
[self getLocationFromAddressString:#"chennai"];
just pass this in your browser
http://maps.google.com/maps/api/geocode/json?sensor=false&address=chennai
and you will have json format with lat and lon
http://maps.google.com/maps/api/geocode/json?sensor=false&address=#"your city name here"
NSString *address = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%# %# %#", self.streetField.text, self.cityField.text, self.countryField.text];
the usage of this method....
CLLocationCoordinate2D center;
center=[self getLocationFromAddressString:#"uthangarai"];
double latFrom=¢er.latitude;
double lonFrom=¢er.longitude;
NSLog(#"View Controller get Location Logitute : %f",latFrom);
NSLog(#"View Controller get Location Latitute : %f",lonFrom);
Someone looking for Swift 2.0 solution can use below :
let address = "1 Infinite Loop, CA, USA"
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(address, completionHandler: {(placemarks, error) -> Void in
if((error) != nil){
print("Error", error)
}
if let placemark = placemarks?.first {
let coordinates:CLLocationCoordinate2D = placemark.location!.coordinate
coordinates.latitude
coordinates.longitude
print("lat", coordinates.latitude)
print("long", coordinates.longitude)
}
})
Try this,
NSString *address = [NSString stringWithFormat:#"%#,%#,%#", self.streetField.text, self.cityField.text,self.countryField.text];
[self.geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error)
{
if(!error)
{
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(#"%f",placemark.location.coordinate.latitude);
NSLog(#"%f",placemark.location.coordinate.longitude);
NSLog(#"%#",[NSString stringWithFormat:#"%#",[placemark description]]);
}
else
{
NSLog(#"There was a forward geocoding error\n%#",[error localizedDescription]);
}
}
];
Swift
public func getLocationFromAddress(address : String) -> CLLocationCoordinate2D {
var lat : Double = 0.0
var lon : Double = 0.0
do {
let url = String(format: "https://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", (address.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)!))
let result = try Data(contentsOf: URL(string: url)!)
let json = JSON(data: result)
lat = json["results"][0]["geometry"]["location"]["lat"].doubleValue
lon = json["results"][0]["geometry"]["location"]["lng"].doubleValue
}
catch let error{
print(error)
}
return CLLocationCoordinate2D(latitude: lat, longitude: lon)
}
I used SwiftyJSON but you can parse the JSON response however you want
- (IBAction)forwardButton:(id)sender
{
if([self.address.text length])
{
NSString *place = self.address.text;
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
__unsafe_unretained RTGeoCoderViewController *weakSelf = self;
[geocoder geocodeAddressString:place completionHandler:^(NSArray* placemarks, NSError* error)
{
NSLog(#"completed");
if ( error )
{
NSLog(#"error = %#", error );
dispatch_async(dispatch_get_main_queue(),
^{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[self errorMessage:error.code] delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
});
}
else
{
NSLog(#"%#",placemarks);
}
}];
}
}
Try this
- (void)getAddressFromAdrress:(NSString *)address withCompletationHandle:(void (^)(NSDictionary *))completationHandler {
CLGeocoder *geoCoder = [[CLGeocoder alloc] init];
//Get the address through geoCoder
[geoCoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
if ([placemarks count] > 0 && !error) {
//get the address from placemark
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSString *locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
CLLocation *location = placemark.location;
CLLocationCoordinate2D coordinate = location.coordinate;
_latitudeUserLocation = coordinate.latitude;
_longitudeUserLocation = coordinate.longitude;
NSString *postalCode = placemark.addressDictionary[(NSString*)kABPersonAddressZIPKey];
if (postalCode == nil) postalCode = #"";
if (locatedAt == nil) locatedAt = #"";
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
postalCode ,kPostalCode,
locatedAt ,kFullAddress,
nil];
completationHandler(dictionary);
} else {
completationHandler(nil);
}
}];
}
So I'm doing this -
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
if (newLocation != nil) {
currentLocation = newLocation;
}
currentLocationString = [[NSMutableString alloc] initWithString:#""];
geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
if (error == nil && [placemarks count] > 0) {
CLPlacemark* currentLocPlacemark = [placemarks lastObject];
NSLog(#"FORMATTED ADDR DICT : %#", currentLocPlacemark.addressDictionary);
[currentLocationString appendString: currentLocPlacemark.addressDictionary[#"Street"]];
[currentLocationString appendString: #" "];
[currentLocationString appendString: currentLocPlacemark.addressDictionary[#"City"]];
NSLog(#"%#", currentLocationString);
[currentLocationString appendString: #" "];
[currentLocationString appendString: currentLocPlacemark.addressDictionary[#"Country"]];
NSLog(#"CURRENTLOCATION STRING : %#", currentLocationString);
} else {
NSLog(#"%#", error.debugDescription);
}
} ];
[locationManager stopUpdatingLocation];
}
Sometimes the currentLocationString has two copies of the same string appended, and sometimes it does not. This seems like a threading issue - what's going on? Is there a synchronized keyword in objective C, or some way of getting around this through cocoa-touch?
It happens when reverseGeocodeLocation has not finished its execution and you receive new location update. So, in the completionHandler, you will append the string in the same variable.
To avoid it, you should create the copy of currentLocationString inside the completionHandler.