Вы дали нам пример кода:
let currentLatCoord = manager.location?.coordinate.latitude
let currentLongCoord = manager.location?.coordinate.longitude
CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: currentLatCoord!, longitude: currentLongCoord!)) { (placemarks, error) -> Void in
if error != nil {
print(error)
return
}
let placeArray = placemarks as [CLPlacemark]!
var placeMark: CLPlacemark
placeMark = placeArray![0]
self.locationLabel.text = String(placeMark.addressDictionary?["Thoroughfare"]!)
}
Вы можете более корректно обрабатывать nil
значения, если вы используете if let
конструкцию:
CLGeocoder().reverseGeocodeLocation(manager.location!) { placemarks, error in
guard error == nil else {
print(error)
return
}
if let placemark = placemarks?.first {
self.locationLabel.text = placemark.thoroughfare
}
}
И, конечно, если вы звоните в этом неоднократно, я бы не стал повторно создавать новый CLGeocoder
каждый раз, но, надеюсь, это иллюстрирует шаблон.
Но, как вы можете видеть, вы можете избежать выделения широты и долготы из свойства location, чтобы создать новый объект CLLocation
, просто используя manager.location
. Аналогично, вы можете использовать свойство thoroughfare
, что избавит вас от необходимости использовать значение addressDictionary
.
Ключевое наблюдение, упомянутое выше Крейгом, заключается в том, чтобы неукоснительно использовать оператор принудительной разворачивания !
, если вы не уверены, что переменная никогда не может быть nil
. Аналогично, не используйте синтаксис [0]
, если вы не знаете, что в массиве есть хотя бы один элемент (поэтому я использую first
, который является необязательным, для которого я могу легко протестировать).
Честно говоря, я бы даже убедиться, что location
был действительным (не nil
и с неотрицательным horizontalAccuracy
, а отрицательное значение указывает на то, что координаты являются недопустимыми):
if let location = manager.location where location.horizontalAccuracy >= 0 {
CLGeocoder().reverseGeocodeLocation(location) { placemarks, error in
guard error == nil else {
print(error)
return
}
if let placemark = placemarks?.first {
self.locationLabel.text = placemark.thoroughfare
}
}
}
Это ISN» t всегда 'nil'. он работает около 4 обновлений, много времени дольше. В конце концов, однако, он падает. только через некоторое время.Я также тестировал его, и он, казалось, обновлялся в реальном времени, а также в симуляции для нескольких обновлений. –
Я также обнаружил, что иногда появляется очень похожая ошибка, когда приложение запускается в строке: 'CLGeocoder(). ReverseGeocodeLocation (CLLocation (широта: currentLatCoord !, longitude: currentLongCoord!)) {(Меток, ошибка) -> Пустота in' –
Конечно, но вам нужно защититься от случаев, когда * * будет 'nil'. Обратное геокодирование не всегда гарантируется быть точным и не имеет одинаковых значений каждый раз, когда выполняется обратный вызов. И ваша «очень похожая ошибка», скорее всего, представляет собой случай силы, разворачивающей «currentLatCoord» и «currentLongCoord», которые, вероятно, «nil». Вы должны * проверить перед использованием * с помощью инструкции 'if let'. –