// // LNLocationManager.swift // Lanu // // Created by OneeChan on 2025/12/25. // import Foundation import CoreLocation import AutoCodable @AutoCodable private class LNUserLocation: Codable { var latitude: CLLocationDegrees = 0 var longitude: CLLocationDegrees = 0 init(latitude: CLLocationDegrees, longitude: CLLocationDegrees) { self.latitude = latitude self.longitude = longitude } } class LNLocationManager: NSObject { static let shared = LNLocationManager() private let locationManager = CLLocationManager() private var curLocation: LNUserLocation? = LNUserDefaults[.location] { didSet { LNUserDefaults[.location] = curLocation } } private var lastTime: TimeInterval? = LNUserDefaults[.reportLocationTime] { didSet { LNUserDefaults[.reportLocationTime] = lastTime } } private var shouldReportLocation: Bool { guard curLocation != nil, let lastTime else { return true } return curTime - lastTime > 3 * 60 * 60 // 3 小时内不拉取 } private override init() { super.init() locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest // 最高精度 LNEventDeliver.addObserver(self) } } extension LNLocationManager: CLLocationManagerDelegate { func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { guard let userLocation = locations.last else { return } guard -userLocation.timestamp.timeIntervalSinceNow < 5 else { // 只使用5秒内的位置 Log.d("位置过期,忽略") return } guard userLocation.horizontalAccuracy >= 0, userLocation.horizontalAccuracy <= 100 else { Log.d("位置精度不足(\(userLocation.horizontalAccuracy)米),继续等待") return } manager.stopUpdatingLocation() curLocation = .init(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude) lastTime = curTime uploadLocation(coordinate: userLocation.coordinate) } func locationManager(_ manager: CLLocationManager, didFailWithError error: any Error) { } } extension LNLocationManager: LNAccountManagerNotify { func onUserLogin() { getLocationIfNeed() } } extension LNLocationManager { private func getLocationIfNeed() { if shouldReportLocation { locationManager.requestWhenInUseAuthorization() // 请求使用时的定位权限 locationManager.startUpdatingLocation() // 开始更新位置 } } private func uploadLocation(coordinate: CLLocationCoordinate2D) { LNHttpManager.shared.uploadLocation( longitude: coordinate.longitude, latitude: coordinate.latitude ) { _ in } } }