2016-12-28 10 views
1

Я пытаюсь сгенерировать форматированный полный адрес с помощью CLGeocoder в Swift 8. Я ссылался на этот поток SO, чтобы получить код, приведенный ниже.Swift - Создание формата адреса из обратного геокодирования

Однако иногда приложение падает с ошибкой «ноль» в строке:

//Address dictionary 
print(placeMark.addressDictionary ?? "") 

Вопросы:

  1. Как я могу объединить эти значения, полученные из Геокодера с образованием полный адрес? (Улица + Город + и т. Д.)
  2. Как обрабатывать ошибку nil, которую я получаю, когда func не может найти адрес?

Полный код:

func getAddress() -> String { 
     var address: String = "" 

     let geoCoder = CLGeocoder() 
     let location = CLLocation(latitude: selectedLat, longitude: selectedLon) 
     //selectedLat and selectedLon are double values set by the app in a previous process 

     geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in 

      // Place details 
      var placeMark: CLPlacemark! 
      placeMark = placemarks?[0] 

      // Address dictionary 
      //print(placeMark.addressDictionary ?? "") 

      // Location name 
      if let locationName = placeMark.addressDictionary!["Name"] as? NSString { 
       //print(locationName) 
      } 

      // Street address 
      if let street = placeMark.addressDictionary!["Thoroughfare"] as? NSString { 
       //print(street) 
      } 

      // City 
      if let city = placeMark.addressDictionary!["City"] as? NSString { 
       //print(city) 
      } 

      // Zip code 
      if let zip = placeMark.addressDictionary!["ZIP"] as? NSString { 
       //print(zip) 
      } 

      // Country 
      if let country = placeMark.addressDictionary!["Country"] as? NSString { 
       //print(country) 
      } 

     }) 

     return address; 
    } 

ответ

17
func getAddressFromLatLon(pdblLatitude: String, withLongitude pdblLongitude: String) { 
     var center : CLLocationCoordinate2D = CLLocationCoordinate2D() 
     let lat: Double = Double("\(pdblLatitude)")! 
     //21.228124 
     let lon: Double = Double("\(pdblLongitude)")! 
     //72.833770 
     let ceo: CLGeocoder = CLGeocoder() 
     center.latitude = lat 
     center.longitude = lon 

     let loc: CLLocation = CLLocation(latitude:center.latitude, longitude: center.longitude) 


     ceo.reverseGeocodeLocation(loc, completionHandler: 
      {(placemarks, error) in 
       if (error != nil) 
       { 
        print("reverse geodcode fail: \(error!.localizedDescription)") 
       } 
       let pm = placemarks! as [CLPlacemark] 

       if pm.count > 0 { 
        let pm = placemarks![0] 
        print(pm.country) 
        print(pm.locality) 
        print(pm.subLocality) 
        print(pm.thoroughfare) 
        print(pm.postalCode) 
        print(pm.subThoroughfare) 
        var addressString : String = "" 
        if pm.subLocality != nil { 
         addressString = addressString + pm.subLocality! + ", " 
        } 
        if pm.thoroughfare != nil { 
         addressString = addressString + pm.thoroughfare! + ", " 
        } 
        if pm.locality != nil { 
         addressString = addressString + pm.locality! + ", " 
        } 
        if pm.country != nil { 
         addressString = addressString + pm.country! + ", " 
        } 
        if pm.postalCode != nil { 
         addressString = addressString + pm.postalCode! + " " 
        } 


        print(addressString) 
       } 
     }) 

    } 
+0

и последний адрес печати строки. у вас есть весь адрес –

+0

Есть проблема с этим. Функция func проходит этот процесс перед ожиданием обработки адреса из LatLng.Поэтому я получаю пустую строку – Dinuka

+1

@RickGrimesLikesWalkerSoup проверяет весь мой метод, который я использую в своем проекте. вы также можете использовать его –

2

Объединяем вы можете просто заменить return address этим:

return "\(locationName), \(street), \(city), \(zip), \(country)" 
+0

Это не дает ответа на вопрос. Чтобы критиковать или просить разъяснения у автора, оставьте комментарий ниже их сообщения. - [Из обзора] (/ review/low-quality-posts/14721054) – Mayur

+0

@Mack Этот ответ на вопрос «как конкатенировать ...» – Makaille

+0

Возможно, вам следует добавить еще несколько объяснений о том, что делать, как использовать, где использовать эту линию и некоторые вещи. Теперь просто просто размещение 1 строки не всегда получается правильным решением. – Mayur

1
  1. Для фиксации пустого адреса проблемы, либо вы можете используйте свойство класса для хранения прилагаемого значение или вы можете использовать замыкание, чтобы вернуть значение обратно в вызывающей функцию
  2. Для фиксации аварии вам нужно, чтобы избежать сил разворачивания из опций

Использования закрытия вы можете сделать это нравится:

// Using closure 
func getAddress(handler: (String) -> Void) 
{ 
    var address: String = "" 
    let geoCoder = CLGeocoder() 
    let location = CLLocation(latitude: selectedLat, longitude: selectedLon) 
    //selectedLat and selectedLon are double values set by the app in a previous process 

    geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in 

     // Place details 
     var placeMark: CLPlacemark? 
     placeMark = placemarks?[0] 

     // Address dictionary 
     //print(placeMark.addressDictionary ?? "") 

     // Location name 
     if let locationName = placeMark?.addressDictionary?["Name"] as? String { 
      address += locationName + ", " 
     } 

     // Street address 
     if let street = placeMark?.addressDictionary?["Thoroughfare"] as? String { 
      address += street + ", " 
     } 

     // City 
     if let city = placeMark?.addressDictionary?["City"] as? String { 
      address += city + ", " 
     } 

     // Zip code 
     if let zip = placeMark?.addressDictionary?["ZIP"] as? String { 
      address += zip + ", " 
     } 

     // Country 
     if let country = placeMark?.addressDictionary?["Country"] as? String { 
      address += country 
     } 

     // Passing address back 
     handler(address) 
    }) 
} 

Вы можете вызвать метод, как:

getAddress { (address) in 
    print(address) 
} 
2

Это мой код 4 скор 3

func getAdressName(coords: CLLocation) { 

    CLGeocoder().reverseGeocodeLocation(location) { (placemark, error) in 
      if error != nil { 

       print("Hay un error") 

      } else { 

       let place = placemark! as [CLPlacemark] 

       if place.count > 0 { 
        let place = placemark![0] 

        var adressString : String = "" 

        if place.thoroughfare != nil { 
         adressString = adressString + place.thoroughfare! + ", " 
        } 
        if place.subThoroughfare != nil { 
         adressString = adressString + place.subThoroughfare! + "\n" 
        } 
        if place.locality != nil { 
         adressString = adressString + place.locality! + " - " 
        } 
        if place.postalCode != nil { 
         adressString = adressString + place.postalCode! + "\n" 
        } 
        if place.subAdministrativeArea != nil { 
         adressString = adressString + place.subAdministrativeArea! + " - " 
        } 
        if place.country != nil { 
         adressString = adressString + place.country! 
        } 

        self.lblPlace.text = adressString 
       } 

      } 
     } 
    } 

Вы можете назвать как:

let cityCoords = CLLocation(latitude: newLat, longitude: newLon) 
cityData(coord: cityCoords) 
0

Держа это просто - Полный Swift 3 & 4 совместимого пример View Controller для получения отформатированного адреса строки из местоположения пользователя (добавить в других ключах, доступных в CLPlacemark, если вы хотите получить больше информации в вашей строке):

import UIKit 
import CoreLocation 

class ViewController: UIViewController, CLLocationManagerDelegate { 

let manager = CLLocationManager() 
let geocoder = CLGeocoder() 

var locality = "" 
var administrativeArea = "" 
var country = "" 

override func viewDidLoad() { 
    super.viewDidLoad() 

    manager.delegate = self 
    manager.desiredAccuracy = kCLLocationAccuracyBest 
    manager.requestWhenInUseAuthorization() 
    manager.startUpdatingLocation() 

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
     let location = locations[0] 
     manager.stopUpdatingLocation() 

    geocoder.reverseGeocodeLocation(location, completionHandler: {(placemarks, error) in 
     if (error != nil) { 
      print("Error in reverseGeocode") 
      } 

     let placemark = placemarks! as [CLPlacemark] 
     if placemark.count > 0 { 
      let placemark = placemarks![0] 
      self.locality = placemark.locality! 
      self.administrativeArea = placemark.administrativeArea! 
      self.country = placemark.country! 
     } 
    }) 
} 

func userLocationString() -> String { 
    let userLocationString = "\(locality), \(administrativeArea), \(country)" 
    return userLocationString 
} 

} 

Вызов печати (userLocationString()) в этом примере будет печатать: пригород, штат, страну

Не забудьте добавить Конфиденциальность - Местоположение при использовании Описание использования в ваш файл Info.plist заблаговременно, чтобы позволить пользователю предоставлять разрешения вашему приложению для использования служб определения местоположения.