Integrate Amap SDK to replace CoreLocation and MapKit for all location features.
Unify GPS, reverse geocoding, and map display behind LocationProvider with privacy-gated bootstrap after login, aligned with Android. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -3,12 +3,11 @@
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import CoreLocation
|
||||
import UIKit
|
||||
|
||||
/// 主 Tab 中间扫码按钮结果处理,对齐 Android `MainTabViewModel.signIn`。
|
||||
@MainActor
|
||||
final class MainTabScanHandler: NSObject, CLLocationManagerDelegate {
|
||||
final class MainTabScanHandler {
|
||||
|
||||
var onShowMessage: ((String) -> Void)?
|
||||
var onShowSignIn: ((OrderSignInResponse) -> Void)?
|
||||
@ -18,15 +17,12 @@ final class MainTabScanHandler: NSObject, CLLocationManagerDelegate {
|
||||
var onNavigateBindAcquirer: ((Int) -> Void)?
|
||||
|
||||
private let api: OrderAPI
|
||||
private let locationManager = CLLocationManager()
|
||||
private var locationContinuation: ((Result<CLLocationCoordinate2D, Error>) -> Void)?
|
||||
private let locationProvider: any LocationProviding
|
||||
private(set) var pendingMultiVerify: MultiVerifyParseData?
|
||||
|
||||
init(api: OrderAPI) {
|
||||
init(api: OrderAPI, locationProvider: any LocationProviding = LocationProvider.shared) {
|
||||
self.api = api
|
||||
super.init()
|
||||
locationManager.delegate = self
|
||||
locationManager.desiredAccuracy = kCLLocationAccuracyBest
|
||||
self.locationProvider = locationProvider
|
||||
}
|
||||
|
||||
func handleScanResult(_ scanResult: String) async {
|
||||
@ -141,14 +137,8 @@ final class MainTabScanHandler: NSObject, CLLocationManagerDelegate {
|
||||
}
|
||||
|
||||
private func fetchSpotsForMultiVerify(pending: MultiVerifyParseData) async {
|
||||
let status = locationManager.authorizationStatus
|
||||
guard status == .authorizedWhenInUse || status == .authorizedAlways else {
|
||||
locationManager.requestWhenInUseAuthorization()
|
||||
onShowMessage?("缺少定位权限,功能无法进行")
|
||||
return
|
||||
}
|
||||
do {
|
||||
let coordinate = try await requestLocation()
|
||||
let coordinate = try await locationProvider.requestCoordinate()
|
||||
let response = try await api.multiTravelScenicSpotList(
|
||||
orderNumber: pending.orderNumber,
|
||||
lat: coordinate.latitude,
|
||||
@ -160,35 +150,12 @@ final class MainTabScanHandler: NSObject, CLLocationManagerDelegate {
|
||||
} else {
|
||||
onShowMultiVerifySheet?(spots, spots.first)
|
||||
}
|
||||
} catch LocationProviderError.permissionDenied {
|
||||
onShowMessage?(OrderLocationError.permissionDenied.errorDescription ?? "缺少定位权限,功能无法进行")
|
||||
} catch {
|
||||
onShowMessage?(error.localizedDescription)
|
||||
onShowMessage?((error as? LocalizedError)?.errorDescription ?? error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
private func requestLocation() async throws -> CLLocationCoordinate2D {
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
locationContinuation = { result in
|
||||
switch result {
|
||||
case .success(let coordinate):
|
||||
continuation.resume(returning: coordinate)
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
locationManager.requestLocation()
|
||||
}
|
||||
}
|
||||
|
||||
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
|
||||
guard let location = locations.last else { return }
|
||||
locationContinuation?(.success(location.coordinate))
|
||||
locationContinuation = nil
|
||||
}
|
||||
|
||||
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
|
||||
locationContinuation?(.failure(error))
|
||||
locationContinuation = nil
|
||||
}
|
||||
}
|
||||
|
||||
private extension MainTabScanHandler {
|
||||
|
||||
@ -1,55 +0,0 @@
|
||||
//
|
||||
// OrderLocationProvider.swift
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import CoreLocation
|
||||
|
||||
/// 一次性定位,用于多点位核销拉取打卡点。
|
||||
final class OrderLocationProvider: NSObject, CLLocationManagerDelegate {
|
||||
private let manager = CLLocationManager()
|
||||
private var continuation: ((Result<CLLocationCoordinate2D, Error>) -> Void)?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
manager.delegate = self
|
||||
manager.desiredAccuracy = kCLLocationAccuracyBest
|
||||
}
|
||||
|
||||
func requestCoordinate() async throws -> CLLocationCoordinate2D {
|
||||
let status = manager.authorizationStatus
|
||||
if status == .notDetermined {
|
||||
manager.requestWhenInUseAuthorization()
|
||||
}
|
||||
guard status == .authorizedWhenInUse || status == .authorizedAlways || manager.authorizationStatus == .authorizedWhenInUse else {
|
||||
throw OrderLocationError.permissionDenied
|
||||
}
|
||||
return try await withCheckedThrowingContinuation { continuation in
|
||||
self.continuation = { result in
|
||||
continuation.resume(with: result)
|
||||
}
|
||||
manager.requestLocation()
|
||||
}
|
||||
}
|
||||
|
||||
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
|
||||
guard let location = locations.last else { return }
|
||||
continuation?(.success(location.coordinate))
|
||||
continuation = nil
|
||||
}
|
||||
|
||||
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
|
||||
continuation?(.failure(error))
|
||||
continuation = nil
|
||||
}
|
||||
}
|
||||
|
||||
enum OrderLocationError: LocalizedError {
|
||||
case permissionDenied
|
||||
|
||||
var errorDescription: String? {
|
||||
switch self {
|
||||
case .permissionDenied: "缺少定位权限,功能无法进行"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user