Распределение результатов обратного геокодирования по глобальной переменной
Я использую Swift 4 и Xcode 9.3.1. Я в том числе скриншоты кода.
Я новичок в мобильной разработке / программировании в целом и думал о том, как это сформулировать. Так что это лучшее, что я могу объяснить:
Я создаю приложение, которое получает местоположение пользователя, чтобы отправить им помощь. Приложение получает координаты пользователя и отображает TextView с информацией об адресе. Так что довольно прямая функциональность mapKit / coreLocation. Пока все хорошо: получение координат с помощью startUpdatingLocation() работает нормально, и я использовал Reverse Geocoder, чтобы получить название улицы и местность. Но они - имея в виду расшифрованные строки улиц и населенных пунктов - распечатывают, только если я позвоню им в закрытом помещении, а не за его пределами. Я понял (правильно или неправильно?), Что переменные, которые должны быть доступны для нескольких функций в классе, должны быть объявлены глобально наверху. Однако я не могу понять, как извлечь информацию из этого замыкания, чтобы использовать ее в другом месте.
Я гуглял и читал вопросы в stackOverflow, и я чувствую, что чего-то действительно простого не хватает, но не могу понять, что. То, что я до сих пор безуспешно пытался:
1_ Определение глобальных переменных как пустых строк в начале класса и использование имен переменных внутри замыкания, где происходит обратный метод геокодирования, в попытке сохранить результирующие строки, но когда я пытаюсь распечатать переменные вне замыкания, Глобальная переменная - это еще и пустая строка ("").
[глобальные переменные объявлены вверху] [1]
2_Определение пустого глобального массива строк и добавление информации из замыкания в глобальный массив. Все еще получил пустой массив за пределами закрытия. (так же, как 1)
3_Создайте функцию --func decodedString()- чтобы вернуть данные в виде строки, чтобы я мог использовать их, объявив
*let streetLocation : String = decodedString()*
Однако, когда я объявляю эту функцию следующим образом:
var street = ""
var locality = ""
// Get the street address from the coordinates
func deocodedString() -> String {
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(location) { placemarks, error in
if let placemark = placemarks?.first {
self.street = placemark.name!
self.locality = placemark.locality!
let string = "\(self.street), \(self.locality)"
return string
}
}
}
Я получаю сообщение об ошибке: Неожиданное возвращаемое значение в void функции
неожиданное возвращаемое значение в пустую функцию
Наконец, если я передаю информацию прямо в TextView внутри замыкания с использованием приведенного ниже кода, мой textView успешно обновляется, но я не могу отформатировать строки, что мне нужно сделать, чтобы они выглядели как инструкции по проектированию Я следую (иначе жирный текст, обычный текст и текст разных размеров):
CLGeocoder().reverseGeocodeLocation(location) { placemarks, error in
if let placemark = placemarks?.first {
self.street = placemark.name!
self.locality = placemark.locality!
let string = "\(self.street), \(self.locality)"
self.addressTextView.text = string
}
}
Вот почему я не могу просто пройти через метод textView.text = string.
Я был бы признателен за помощь... Я искал хотя бы StackOverFlow, YouTube и другие учебные места, но я не могу понять, что мне не хватает, или почему мое объявление функции вызывает ошибку. Я уже уничтожил и перевернул свой код несколько раз за последние 24 часа, не получив независимую строку, к которой я могу применить форматирование перед передачей его в textView, и я не знаю, как еще подойти к нему.
1 ответ
При вызове этой функции reverseGeocodeLocation выполняется в фоновом потоке. Так что если вы хотите вернуть адрес в этом методе, вы должны использовать escape-замыкание.
func getaddress(_ position:CLLocationCoordinate2D,completion:@escaping (String)->()) {
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(location) { placemarks, error in
if let placemark = placemarks?.first {
let street = placemark.name!
let locality = placemark.locality!
let string = "\(street), \(locality)"
completion(string)
}
}
}
self.getaddress(position.target) { address in
print(address)
self.addressTextView.text = address
}
У меня была проблема с геокодером Google, чтобы обновить ярлык на экране карты.
Итак, я сделал это, во-первых, создать
быстрое имя файла: GoogleAPI просто называйте его как хотите.
class GoogleAPI {
static let sharedInstance = GoogleAPI()
private init() { }
var addressValue = ""
public func geocoding(lat: Double, long: Double) {
Alamofire.request("https://maps.googleapis.com/maps/api/geocode/json?latlng=\(lat),\(long)&key=YOUR_GOOGLE_KEY").responseJSON { (response) in
if response.result.isSuccess {
let dataJSON : JSON = JSON(response.result.value!)
self.geocoding(json: dataJSON)
} else {
print("Error \(response.result.error!)")
}
}
}
fileprivate func geocoding(json: JSON) {
let json = json["results"]
let address = json[1]["formatted_address"].stringValue
addressValue = address
print("pin address \(addressValue)")
}
}
Это вызов API для Google, чтобы получить все из ответа и проанализировать единственную улицу.
После этого перейдите в свой View Controller с картой, где находится значок, карта и т. Д.
Установите булавку, маркер, чтобы быть перетаскиваемым. [marker1.isDraggable = true
]
Затем добавьте эту функцию
mapView(_ mapView: GMSMapView, маркер didEndDragging: GMSMarker)
и добавьте вызов сверху вот так:
func mapView(_ mapView: GMSMapView, didEndDragging marker: GMSMarker) {
GoogleAPI.sharedInstance.geocoding(lat: marker.position.latitude, long: marker.position.longitude)
DispatchQueue.main.async {
self.txtSearch.text = GoogleAPI.sharedInstance.addressValue
}
}
txtSearch - это мое текстовое поле поиска.
да, я знаю, что это можно сделать лучше, но нет времени. это работает
Swift 4.2