SwiftUI地理定位可选值问题:反向编码地址无法存入Core Data
问题核心原因
你的问题本质是反向地理编码属于异步操作,和可选值处理无关。CLGeocoder().reverseGeocodeLocation 会在系统完成地址解析后才执行回调,而你当前的代码用同步逻辑拿异步结果,自然拿不到有效值。
现有代码的两处明显错误
getLocation()方法声明了String类型返回值,但你没有写方法级别的return语句。回调闭包里的return addr只会返回到闭包作用域,不会给getLocation()本身返回值,这个方法实际返回的是空值。- 你在
saveButton()里调用getLocation()后立刻执行Core Data存储逻辑,此时地址解析还没完成,addr还没被赋值,存储的自然是空内容。
修正后代码
调整逻辑:等地址解析完成拿到有效值后,再执行Core Data存储操作
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.getLocationThenSave() }) { HStack { Spacer() Text ("Save") Spacer() } } } .navigationBarHidden(true) .navigationViewStyle(StackNavigationViewStyle()) } // 抽离Core Data保存逻辑,接收解析好的地址作为入参 func saveEntry(with address: String) { let newEntry = CurrTrans(context: viewContext) newEntry.id = UUID() newEntry.entryDT = entryDT newEntry.entryDsc = entryDsc newEntry.moneyD = moneyD newEntry.entryLat = entryLat newEntry.entryLong = entryLong newEntry.address = address print("newEntry.address = \(newEntry.address ?? "")") do { try viewContext.save() } catch { print(error.localizedDescription) } } // 异步获取地址,拿到结果后再调用保存方法 func getLocationThenSave() { let result = lm.getLocationCoordinates() entryLat = result.0 entryLong = result.1 let location = CLLocation(latitude: entryLat, longitude: entryLong) location.placemark { placemark, error in guard let placemark = placemark else { print("Error:", error ?? "nil") // 地址解析失败时传入默认值避免空存储 self.saveEntry(with: "Unknown") return } let formattedAddr = placemark.postalAddressFormatted ?? "Unknown" print("formatted address: \(formattedAddr)") self.addr = formattedAddr // 拿到有效地址后执行保存 self.saveEntry(with: formattedAddr) } } }
位置管理器的扩展代码不需要修改,可保留原有逻辑。
内容的提问来源于stack exchange,提问作者Galen Smith
相关产品推荐
相关产品推荐

