I want to find current location name from latitude and longitude,
Here is my code snippet I tried but my log shows null value in all the places except in place
Try this
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
//..NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
if (error == nil && [placemarks count] > 0) {
placemark = [placemarks lastObject];
lblgetaddrees.text = [NSString stringWithFormat:@"%@,%@,%@,%@,%@,%@",
placemark.subThoroughfare, placemark.thoroughfare,
placemark.postalCode, placemark.locality,
placemark.administrativeArea,
placemark.country];
} else {
//..NSLog(@"%@", error.debugDescription);
}
} ];
Once you have latitude
, longitude
values of a location you can use CLGeocoder
here is a tutorial which might help you.
In Swift 4.1 and Xcode 9.4.1, this is one of my solution. Here i'm using geocode API to get the complete address. With this api i can get the village names also.
I'm using reverseGeocodeLocation but it's not getting village address details or village names, it's getting only near by city names. It's one of the finest solution....
func getAddressForLatLng(latitude: String, longitude: String) { // Call this function
let url = NSURL(string: "https://maps.googleapis.com/maps/api/geocode/json?latlng=\(latitude),\(longitude)")//Here pass your latitude, longitude
print(url!)
let data = NSData(contentsOf: url! as URL)
if data != nil {
let json = try! JSONSerialization.jsonObject(with: data! as Data, options: JSONSerialization.ReadingOptions.allowFragments) as! NSDictionary
print(json)
let status = json["status"] as! String
if status == "OK" {
if let result = json["results"] as? NSArray {
if result.count > 0 {
if let addresss:NSDictionary = result[0] as? NSDictionary {
if let address = addresss["address_components"] as? NSArray {
var newaddress = ""
var number = ""
var street = ""
var city = ""
var state = ""
var zip = ""
var country = ""
if(address.count > 1) {
number = (address.object(at: 0) as! NSDictionary)["short_name"] as! String
}
if(address.count > 2) {
street = (address.object(at: 1) as! NSDictionary)["short_name"] as! String
}
if(address.count > 3) {
city = (address.object(at: 2) as! NSDictionary)["short_name"] as! String
}
if(address.count > 4) {
state = (address.object(at: 4) as! NSDictionary)["short_name"] as! String
}
if(address.count > 6) {
zip = (address.object(at: 6) as! NSDictionary)["short_name"] as! String
}
newaddress = "\(number) \(street), \(city), \(state) \(zip)"
print(newaddress)
// OR
//This is second type to fetch pincode, country, state like this type of data
for i in 0..<address.count {
print(((address.object(at: i) as! NSDictionary)["types"] as! Array)[0])
if ((address.object(at: i) as! NSDictionary)["types"] as! Array)[0] == "postal_code" {
zip = (address.object(at: i) as! NSDictionary)["short_name"] as! String
}
if ((address.object(at: i) as! NSDictionary)["types"] as! Array)[0] == "country" {
country = (address.object(at: i) as! NSDictionary)["long_name"] as! String
}
if ((address.object(at: i) as! NSDictionary)["types"] as! Array)[0] == "administrative_area_level_1" {
state = (address.object(at: i) as! NSDictionary)["long_name"] as! String
}
if ((address.object(at: i) as! NSDictionary)["types"] as! Array)[0] == "administrative_area_level_2" {
district = (address.object(at: i) as! NSDictionary)["long_name"] as! String
}
}
}
}
}
}
}
}
}
Call this function like this
self.getAddressForLatLng(latitude: "\(self.lat!)", longitude: "\(self.lng!)")
Swift 5
import CoreLocation
func printAddress() {
if let lat = Double(30.710489), lat != 0.0, let long = Double(76.852386), long != 0.0 {
// Create Location
let location = CLLocation(latitude: lat, longitude: long)
// Geocode Location
CLGeocoder().reverseGeocodeLocation(location) { (placemarks, error) in
// Process Response
self.processResponse(withPlacemarks: placemarks, error: error)
}
}
}
private func processResponse(withPlacemarks placemarks: [CLPlacemark]?, error: Error?) {
var address = ""
if let error = error {
address = "Unable to Reverse Geocode Location (\(error))"
} else {
if let placemarks = placemarks, let placemark = placemarks.first {
address = placemark.compactAddress ?? ""
} else {
address = "No address found"
}
}
print(address)
}
extension CLPlacemark {
var compactAddress: String? {
if let name = name {
var result = name
if let street = thoroughfare {
result += ", \(street)"
}
if let city = locality {
result += ", \(city)"
}
if let postalCode = postalCode {
result += ", \(postalCode)"
}
if let country = country {
result += ", \(country)"
}
return result
}
return nil
}
}
// 2nd Way
func updateLocation(lat:Double,long:Double) {
CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: Double(lat), longitude: Double(long)), completionHandler: { (placemarks, error) -> Void in
if error != nil {
return
}
else {
var location = ""
let pm = placemarks![0]
if pm.addressDictionary!["FormattedAddressLines"] != nil {
location = "\n" + (pm.addressDictionary!["FormattedAddressLines"] as! NSArray).componentsJoined(by: ", ")
}else{
location = "\n" + "NO_ADDRESS_FOUND"
}
}
})
}
Method with completion block:
typedef void(^addressCompletion)(NSString *);
-(void)getAddressFromLocation:(CLLocation *)location complationBlock:(addressCompletion)completionBlock
{
__block CLPlacemark* placemark;
__block NSString *address = nil;
CLGeocoder* geocoder = [CLGeocoder new];
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error)
{
if (error == nil && [placemarks count] > 0)
{
placemark = [placemarks lastObject];
address = [NSString stringWithFormat:@"%@, %@ %@", placemark.name, placemark.postalCode, placemark.locality];
completionBlock(address);
}
}];
}
This is how to use it:
CLLocation* eventLocation = [[CLLocation alloc] initWithLatitude:_latitude longitude:_longitude];
[self getAddressFromLocation:eventLocation complationBlock:^(NSString * address) {
if(address) {
_address = address;
}
}];
I'm giving you snippet which I'm using for resolving address. I'm including comment also at neccessary place to understand the code for you. Besides that feel free to ask any question from snippet if you get fail to understand anything.
Write following snippet in didUpdateToLocation
method
NSLog(@"didUpdateToLocation: %@", newLocation);
CLLocation *currentLocation = newLocation;
if (currentLocation != nil)
NSLog(@"longitude = %.8f\nlatitude = %.8f", currentLocation.coordinate.longitude,currentLocation.coordinate.latitude);
// stop updating location in order to save battery power
[locationManager stopUpdatingLocation];
// Reverse Geocoding
NSLog(@"Resolving the Address");
// “reverseGeocodeLocation” method to translate the locate data into a human-readable address.
// The reason for using "completionHandler" ----
// Instead of using delegate to provide feedback, the CLGeocoder uses “block” to deal with the response. By using block, you do not need to write a separate method. Just provide the code inline to execute after the geocoding call completes.
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error)
{
NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
if (error == nil && [placemarks count] > 0)
{
placemark = [placemarks lastObject];
// strAdd -> take bydefault value nil
NSString *strAdd = nil;
if ([placemark.subThoroughfare length] != 0)
strAdd = placemark.subThoroughfare;
if ([placemark.thoroughfare length] != 0)
{
// strAdd -> store value of current location
if ([strAdd length] != 0)
strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark thoroughfare]];
else
{
// strAdd -> store only this value,which is not null
strAdd = placemark.thoroughfare;
}
}
if ([placemark.postalCode length] != 0)
{
if ([strAdd length] != 0)
strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark postalCode]];
else
strAdd = placemark.postalCode;
}
if ([placemark.locality length] != 0)
{
if ([strAdd length] != 0)
strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark locality]];
else
strAdd = placemark.locality;
}
if ([placemark.administrativeArea length] != 0)
{
if ([strAdd length] != 0)
strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark administrativeArea]];
else
strAdd = placemark.administrativeArea;
}
if ([placemark.country length] != 0)
{
if ([strAdd length] != 0)
strAdd = [NSString stringWithFormat:@"%@, %@",strAdd,[placemark country]];
else
strAdd = placemark.country;
}
Where strAdd will return address using geolocation..
Enjoy Programming !!