|
|
|
@ -23,13 +23,6 @@ public class LocationService: NSObject { |
|
|
|
private var authorizationStatus: CLAuthorizationStatus = .notDetermined |
|
|
|
private var isLocationServicesEnabled: Bool = false |
|
|
|
|
|
|
|
// 高精度定位属性 |
|
|
|
private var locationAttempts: Int = 0 |
|
|
|
private let maxLocationAttempts: Int = 3 |
|
|
|
private let requiredAccuracy: CLLocationAccuracy = 10.0 // 要求精度在10米以内 |
|
|
|
private var bestLocation: CLLocation? |
|
|
|
private var locationTimer: Timer? |
|
|
|
|
|
|
|
// MARK: - 权限回调 |
|
|
|
private var permissionCallback: ((Result<Bool, Error>) -> Void)? |
|
|
|
|
|
|
|
@ -43,11 +36,33 @@ public class LocationService: NSObject { |
|
|
|
self?.locationManager = CLLocationManager() |
|
|
|
self?.locationManager?.delegate = self |
|
|
|
|
|
|
|
// 高精度定位设置 |
|
|
|
self?.locationManager?.desiredAccuracy = kCLLocationAccuracyBestForNavigation // 最高精度 |
|
|
|
self?.locationManager?.distanceFilter = 1 // 降低距离过滤器,更敏感 |
|
|
|
// 正常定位设置 |
|
|
|
self?.locationManager?.desiredAccuracy = kCLLocationAccuracyBest |
|
|
|
self?.locationManager?.distanceFilter = 10 |
|
|
|
|
|
|
|
print("[LocationService] LocationManager 初始化完成,等待权限状态回调") |
|
|
|
|
|
|
|
// 初始化完成后,主动获取一次位置进行预热 |
|
|
|
self?.preWarmLocation() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// 预热定位服务 |
|
|
|
private func preWarmLocation() { |
|
|
|
// 检查权限状态 |
|
|
|
if checkLocationPermission() { |
|
|
|
print("[LocationService] 开始预热定位") |
|
|
|
requestLocation { [weak self] result in |
|
|
|
switch result { |
|
|
|
case .success(let locationData): |
|
|
|
self?.cachedLocationData = locationData |
|
|
|
print("[LocationService] 预热定位成功,已缓存位置数据") |
|
|
|
case .failure(let error): |
|
|
|
print("[LocationService] 预热定位失败: \(error.localizedDescription)") |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
print("[LocationService] 无定位权限,跳过预热") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -95,7 +110,7 @@ public class LocationService: NSObject { |
|
|
|
private func asyncUpdateLocation() { |
|
|
|
// 检查权限 |
|
|
|
if checkLocationPermission() { |
|
|
|
requestHighAccuracyLocation { [weak self] result in |
|
|
|
requestLocation { [weak self] result in |
|
|
|
switch result { |
|
|
|
case .success(let locationData): |
|
|
|
self?.cachedLocationData = locationData |
|
|
|
@ -110,7 +125,7 @@ public class LocationService: NSObject { |
|
|
|
/// 同步获取位置 |
|
|
|
private func syncGetLocation(completion: @escaping (Result<[String: Any], Error>) -> Void) { |
|
|
|
if checkLocationPermission() { |
|
|
|
requestHighAccuracyLocation { [weak self] result in |
|
|
|
requestLocation { [weak self] result in |
|
|
|
switch result { |
|
|
|
case .success(let locationData): |
|
|
|
self?.cachedLocationData = locationData |
|
|
|
@ -168,8 +183,8 @@ public class LocationService: NSObject { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// 高精度定位方法 |
|
|
|
private func requestHighAccuracyLocation(completion: @escaping (Result<LocationData, Error>) -> Void) { |
|
|
|
/// 正常定位方法 |
|
|
|
private func requestLocation(completion: @escaping (Result<LocationData, Error>) -> Void) { |
|
|
|
DispatchQueue.main.async { [weak self] in |
|
|
|
guard let self = self else { return } |
|
|
|
|
|
|
|
@ -190,10 +205,6 @@ public class LocationService: NSObject { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
// 重置状态 |
|
|
|
self.locationAttempts = 0 |
|
|
|
self.bestLocation = nil |
|
|
|
|
|
|
|
// 设置回调 |
|
|
|
self.currentLocationCallback = { result in |
|
|
|
switch result { |
|
|
|
@ -217,41 +228,22 @@ public class LocationService: NSObject { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
print("[LocationService] 开始高精度连续定位") |
|
|
|
// 开始连续定位 |
|
|
|
locationManager.startUpdatingLocation() |
|
|
|
|
|
|
|
// 设置超时定时器(15秒) |
|
|
|
self.locationTimer = Timer.scheduledTimer(withTimeInterval: 15.0, repeats: false) { _ in |
|
|
|
self.stopLocationUpdates() |
|
|
|
if let bestLocation = self.bestLocation { |
|
|
|
self.processLocation(bestLocation) |
|
|
|
} else { |
|
|
|
let callback = self.currentLocationCallback |
|
|
|
self.currentLocationCallback = nil |
|
|
|
callback?(.failure(NSError(domain: "LocationService", code: -9, userInfo: [NSLocalizedDescriptionKey: "无法获取满足精度要求的位置"]))) |
|
|
|
} |
|
|
|
} |
|
|
|
print("[LocationService] 开始正常定位") |
|
|
|
// 使用单次定位 |
|
|
|
locationManager.requestLocation() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// 停止位置更新 |
|
|
|
private func stopLocationUpdates() { |
|
|
|
locationManager?.stopUpdatingLocation() |
|
|
|
locationTimer?.invalidate() |
|
|
|
locationTimer = nil |
|
|
|
} |
|
|
|
|
|
|
|
/// 处理位置数据 |
|
|
|
private func processLocation(_ location: CLLocation) { |
|
|
|
let locationInfo: [String: Any] = [ |
|
|
|
"user_lng": String(location.coordinate.longitude), |
|
|
|
"user_lat": String(location.coordinate.latitude), |
|
|
|
"timestamp": Date().timeIntervalSince1970 * 1000, |
|
|
|
"accuracy": location.horizontalAccuracy // 添加精度信息 |
|
|
|
"accuracy": location.horizontalAccuracy |
|
|
|
] |
|
|
|
|
|
|
|
print("[LocationService] 处理最终位置,精度: \(location.horizontalAccuracy)m") |
|
|
|
print("[LocationService] 处理位置,精度: \(location.horizontalAccuracy)m") |
|
|
|
|
|
|
|
// 更新缓存 |
|
|
|
cachedLocationData = LocationData( |
|
|
|
@ -288,8 +280,7 @@ extension LocationService: CLLocationManagerDelegate { |
|
|
|
} |
|
|
|
|
|
|
|
print("[LocationService] 位置更新: lat=\(location.coordinate.latitude), lng=\(location.coordinate.longitude)") |
|
|
|
print("[LocationService] 水平精度: \(location.horizontalAccuracy)m, 垂直精度: \(location.verticalAccuracy)m") |
|
|
|
print("[LocationService] 位置时间: \(location.timestamp)") |
|
|
|
print("[LocationService] 水平精度: \(location.horizontalAccuracy)m") |
|
|
|
|
|
|
|
// 过滤无效位置 |
|
|
|
guard location.horizontalAccuracy >= 0 else { |
|
|
|
@ -304,39 +295,14 @@ extension LocationService: CLLocationManagerDelegate { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
locationAttempts += 1 |
|
|
|
|
|
|
|
// 检查是否满足精度要求 |
|
|
|
if location.horizontalAccuracy <= requiredAccuracy { |
|
|
|
print("[LocationService] 获得高精度位置,精度: \(location.horizontalAccuracy)m") |
|
|
|
stopLocationUpdates() |
|
|
|
processLocation(location) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
// 保存最佳位置 |
|
|
|
if bestLocation == nil || location.horizontalAccuracy < bestLocation!.horizontalAccuracy { |
|
|
|
bestLocation = location |
|
|
|
print("[LocationService] 更新最佳位置,精度: \(location.horizontalAccuracy)m") |
|
|
|
} |
|
|
|
|
|
|
|
// 达到最大尝试次数,使用最佳位置 |
|
|
|
if locationAttempts >= maxLocationAttempts { |
|
|
|
print("[LocationService] 达到最大尝试次数,使用最佳位置") |
|
|
|
stopLocationUpdates() |
|
|
|
if let bestLocation = bestLocation { |
|
|
|
processLocation(bestLocation) |
|
|
|
} |
|
|
|
} |
|
|
|
// 处理位置 |
|
|
|
processLocation(location) |
|
|
|
} |
|
|
|
|
|
|
|
public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { |
|
|
|
print("[LocationService] didFailWithError 被调用") |
|
|
|
print("[LocationService] 位置获取失败: \(error.localizedDescription)") |
|
|
|
print("[LocationService] 错误代码: \((error as NSError).code)") |
|
|
|
print("[LocationService] 错误域: \((error as NSError).domain)") |
|
|
|
|
|
|
|
stopLocationUpdates() |
|
|
|
let callback = currentLocationCallback |
|
|
|
currentLocationCallback = nil |
|
|
|
callback?(.failure(error)) |
|
|
|
|