使用来自locationManager的坐标,我想显示通过反向geoLocation在底部获得位置(地址)的地图。坐标和地图显示正确,但我在生成地址时遇到了问题。我试图遵循示例代码在查找城市名称和国家从纬度和经度在Swift在节iOS 11或更高版本. 示例中显示的两个扩展(CLPlacemark和CLLocation)与我使用的相同。因此,尽管我遵循示例用法,但似乎没有正确处理异步Placemark函数。函数getLocation()正确地显示了地址,但是它没有返回到saveButton()。
对于异步函数返回的任何帮助都将不胜感激。
struct EntryView: View {
@Environment(.managedObjectContext) var viewContext // core data
@ObservedObject private var lm = LocationManager() // location
@State private var entryLat: Double = 0.0
@State private var entryLong: Double = 0.0
@State private var addr: String = ""
var body: some View {
GeometryReader { g in
List {
Button(action: {
self.saveButton() // save entry button pressed
}) {
HStack {
Spacer()
Text ("Save")
Spacer()
}
}
}
.navigationBarHidden(true)
.navigationViewStyle(StackNavigationViewStyle())
}
// the save button has been pressed
func saveButton() {
// get coordinates and address
let addr = getLocation()
print("addr = (addr)") // nothing displayed here except addr
// save entry to core data
let newEntry = CurrTrans(context: viewContext)
newEntry.id = UUID()
newEntry.entryDT = entryDT // entry date
newEntry.entryDsc = entryDsc // entry description
newEntry.moneyD = moneyD // money as double
newEntry.entryLat = entryLat // store location for maps
newEntry.entryLong = entryLong
newEntry.address = addr // formatted address
print("newEntry.address = (newEntry.address ?? "")")
do {
try viewContext.save()
} catch {
print(error.localizedDescription)
}
}
func getLocation() -> String {
// get location coordinates
let result = lm.getLocationCoordinates()
entryLat = result.0
entryLong = result.1
// get location address
let location = CLLocation(latitude: entryLat, longitude: entryLong)
location.placemark { placemark, error in
guard let placemark = placemark else {
print("Error:", error ?? "nil")
return
}
print("formatted address: (placemark.postalAddressFormatted ?? "")")
addr = placemark.postalAddressFormatted ?? "Unknown"
return addr
}
}
}
下面的代码是位置管理器的一部分
extension CLLocation {
func placemark(completion: @escaping (_ placemark: CLPlacemark?, _ error: Error?) -> ()) {
CLGeocoder().reverseGeocodeLocation(self) { completion($0?.first, $1) }
}
}
extension CLPlacemark {
/// street name, eg. Infinite Loop
var streetName: String? { thoroughfare }
/// // eg. 1
var streetNumber: String? { subThoroughfare }
/// city, eg. Cupertino
var city: String? { locality }
/// neighborhood, common name, eg. Mission District
var neighborhood: String? { subLocality }
/// state, eg. CA
var state: String? { administrativeArea }
/// county, eg. Santa Clara
var county: String? { subAdministrativeArea }
/// zip code, eg. 95014
var zipCode: String? { postalCode }
/// postal address formatted
var postalAddressFormatted: String? {
guard let postalAddress = postalAddress else { return nil }
return CNPostalAddressFormatter().string(from: postalAddress)
}
}
您的代码无法编译。当你尝试return
addr '时,编译器会给出一个关于Unexpected non-void return value in void function
的警告,因为闭包有一个非空返回类型。
请使用完成处理程序。
可能像这样:
func getLocation(completion: @escaping (String) -> Void) {
// get location coordinates
let result = lm.getLocationCoordinates()
entryLat = result.0
entryLong = result.1
// get location address
let location = CLLocation(latitude: entryLat, longitude: entryLong)
location.placemark { placemark, error in
guard let placemark = placemark else {
print("Error:", error ?? "nil")
return
}
print("formatted address: (placemark.postalAddressFormatted ?? "")")
addr = placemark.postalAddressFormatted ?? "Unknown"
completion(addr)
}
}
前面,在saveButton
中:
func saveButton() {
// get coordinates and address
getLocation { addr in
print("addr = (addr)")
self.addr = addr
//do your CoreData code that depends on addr here
}
//don't try to use addr here, outside the completion handler
}
您的body
中也缺少}