异步GeoLocation返回



使用来自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)
}
}

您的代码无法编译。当你尝试returnaddr '时,编译器会给出一个关于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中也缺少}

相关内容

  • 没有找到相关文章

最新更新