65 lines
1.9 KiB
Swift
65 lines
1.9 KiB
Swift
//
|
||
// LocationGeocoder.swift
|
||
// suixinkan
|
||
//
|
||
|
||
import Foundation
|
||
|
||
/// 高德逆地理编码封装,对齐 Android `GeocodeSearch`。
|
||
final class LocationGeocoder: NSObject, AMapSearchDelegate {
|
||
|
||
static let shared = LocationGeocoder()
|
||
|
||
private var searchAPI: AMapSearchAPI?
|
||
private var continuation: CheckedContinuation<String, Never>?
|
||
|
||
private override init() {
|
||
super.init()
|
||
}
|
||
|
||
/// 将坐标解析为可读地址。
|
||
func reverseGeocode(latitude: Double, longitude: Double) async -> String {
|
||
do {
|
||
try AMapBootstrap.requireConfigured()
|
||
} catch {
|
||
return ""
|
||
}
|
||
|
||
return await withCheckedContinuation { continuation in
|
||
self.continuation?.resume(returning: "")
|
||
self.continuation = continuation
|
||
|
||
guard let api = makeSearchAPI() else {
|
||
continuation.resume(returning: "")
|
||
return
|
||
}
|
||
let request = AMapReGeocodeSearchRequest()
|
||
request.location = AMapGeoPoint.location(withLatitude: CGFloat(latitude), longitude: CGFloat(longitude))
|
||
request.requireExtension = true
|
||
request.radius = 200
|
||
api.aMapReGoecodeSearch(request)
|
||
}
|
||
}
|
||
|
||
func onReGeocodeSearchDone(_ request: AMapReGeocodeSearchRequest!, response: AMapReGeocodeSearchResponse!) {
|
||
let address = response?.regeocode?.formattedAddress ?? ""
|
||
continuation?.resume(returning: address)
|
||
continuation = nil
|
||
}
|
||
|
||
func aMapSearchRequest(_ request: Any!, didFailWithError error: Error!) {
|
||
continuation?.resume(returning: "")
|
||
continuation = nil
|
||
}
|
||
|
||
private func makeSearchAPI() -> AMapSearchAPI? {
|
||
if let searchAPI {
|
||
return searchAPI
|
||
}
|
||
guard let api = AMapSearchAPI() else { return nil }
|
||
api.delegate = self
|
||
searchAPI = api
|
||
return api
|
||
}
|
||
}
|