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:
2026-07-07 11:49:22 +08:00
parent d2879ad7e2
commit cfcd3eee6f
29 changed files with 748 additions and 240 deletions

View File

@ -110,17 +110,13 @@ final class LocationReportViewController: BaseViewController {
}
private func requestLocationIfNeeded() {
let status = CLLocationManager.authorizationStatus()
switch status {
case .authorizedAlways, .authorizedWhenInUse:
viewModel.startLocation()
case .notDetermined:
CLLocationManager().requestWhenInUseAuthorization()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
self?.viewModel.startLocation()
Task {
do {
try await LocationProvider.shared.ensureLocationPermission()
viewModel.startLocation()
} catch {
showToast((error as? LocalizedError)?.errorDescription ?? error.localizedDescription)
}
default:
showToast("需要定位权限才能使用此功能")
}
}

View File

@ -3,7 +3,7 @@
// suixinkan
//
import MapKit
import CoreLocation
import SnapKit
import UIKit
@ -287,21 +287,22 @@ final class LocationReportBottomActionView: UIControl {
}
}
/// MKMapView
final class LocationReportMapView: UIView, MKMapViewDelegate {
/// `MAMapView`
final class LocationReportMapView: UIView, MAMapViewDelegate {
var onMapTap: ((CLLocationCoordinate2D) -> Void)?
let mapView = MKMapView()
private var markerAnnotation: MKPointAnnotation?
let mapView: MAMapView
private var markerAnnotation: MAPointAnnotation?
override init(frame: CGRect) {
_ = AMapBootstrap.configureIfNeeded()
mapView = MAMapView(frame: .zero)
super.init(frame: frame)
mapView.delegate = self
mapView.showsUserLocation = true
mapView.showsCompass = false
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
mapView.addGestureRecognizer(tap)
mapView.zoomLevel = 15
addSubview(mapView)
mapView.snp.makeConstraints { make in
make.edges.equalToSuperview()
@ -314,27 +315,22 @@ final class LocationReportMapView: UIView, MKMapViewDelegate {
}
func centerOnUserLocation() {
guard let coordinate = mapView.userLocation.location?.coordinate else { return }
let coordinate = mapView.userLocation.location?.coordinate
guard let coordinate, CLLocationCoordinate2DIsValid(coordinate) else { return }
setCenter(coordinate)
}
func setCenter(_ coordinate: CLLocationCoordinate2D, animated: Bool = true) {
let region = MKCoordinateRegion(center: coordinate, latitudinalMeters: 800, longitudinalMeters: 800)
mapView.setRegion(region, animated: animated)
mapView.setCenter(coordinate, animated: animated)
mapView.setZoomLevel(15, animated: animated)
}
func zoomIn() {
var region = mapView.region
region.span.latitudeDelta *= 0.5
region.span.longitudeDelta *= 0.5
mapView.setRegion(region, animated: true)
mapView.setZoomLevel(mapView.zoomLevel + 1, animated: true)
}
func zoomOut() {
var region = mapView.region
region.span.latitudeDelta = min(region.span.latitudeDelta * 2, 180)
region.span.longitudeDelta = min(region.span.longitudeDelta * 2, 180)
mapView.setRegion(region, animated: true)
mapView.setZoomLevel(mapView.zoomLevel - 1, animated: true)
}
func updateMarker(latitude: Double?, longitude: Double?) {
@ -343,15 +339,13 @@ final class LocationReportMapView: UIView, MKMapViewDelegate {
markerAnnotation = nil
}
guard let latitude, let longitude else { return }
let annotation = MKPointAnnotation()
let annotation = MAPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
markerAnnotation = annotation
mapView.addAnnotation(annotation)
}
@objc private func handleTap(_ gesture: UITapGestureRecognizer) {
let point = gesture.location(in: mapView)
let coordinate = mapView.convert(point, toCoordinateFrom: mapView)
func mapView(_ mapView: MAMapView!, didSingleTappedAt coordinate: CLLocationCoordinate2D) {
onMapTap?(coordinate)
}
}

View File

@ -3,6 +3,7 @@
// suixinkan
//
import SafariServices
import SnapKit
import UIKit
@ -212,10 +213,10 @@ final class LoginViewController: BaseViewController {
self?.showToast("注册待接入")
}
viewModel.onUserAgreement = { [weak self] in
self?.showToast("用户协议待接入")
self?.openAgreementURL(AppAgreementURLs.userAgreement)
}
viewModel.onPrivacyPolicy = { [weak self] in
self?.showToast("隐私政策待接入")
self?.openAgreementURL(AppAgreementURLs.privacyPolicy)
}
}
@ -345,6 +346,11 @@ final class LoginViewController: BaseViewController {
view.endEditing(true)
viewModel.onRegister?()
}
private func openAgreementURL(_ url: URL) {
let controller = SFSafariViewController(url: url)
present(controller, animated: true)
}
}
extension LoginViewController: UIGestureRecognizerDelegate {

View File

@ -23,7 +23,7 @@ final class OrdersViewController: BaseViewController, UITableViewDataSource, UIT
private weak var orderSourcePicker: OrderSourcePickerViewController?
private var pendingGiftOrderNumber: String?
private var isFetchingMultiVerifySpots = false
private let locationProvider = OrderLocationProvider()
private let locationProvider: any LocationProviding = LocationProvider.shared
override func setupNavigationBar() {
title = "订单"