优化首页位置上报体验
This commit is contained in:
@ -20,12 +20,12 @@ final class LocationProvider: NSObject, LocationProviding {
|
||||
permissionManager.desiredAccuracy = kCLLocationAccuracyBest
|
||||
}
|
||||
|
||||
func requestSnapshot() async throws -> HomeLocationSnapshot {
|
||||
func requestSnapshot(desiredAccuracy: CLLocationAccuracy = kCLLocationAccuracyBest) async throws -> HomeLocationSnapshot {
|
||||
try AMapBootstrap.requireConfigured()
|
||||
try await ensureLocationPermission()
|
||||
|
||||
let manager = makeLocationManager(
|
||||
desiredAccuracy: kCLLocationAccuracyBest,
|
||||
desiredAccuracy: desiredAccuracy,
|
||||
locatingWithReGeocode: true
|
||||
)
|
||||
return try await withCheckedThrowingContinuation { continuation in
|
||||
|
||||
@ -15,8 +15,8 @@ struct HomeLocationSnapshot: Sendable, Equatable {
|
||||
|
||||
/// 定位服务协议,便于 ViewModel 注入与单元测试 mock。
|
||||
protocol LocationProviding: Sendable {
|
||||
/// 请求当前坐标与地址。
|
||||
func requestSnapshot() async throws -> HomeLocationSnapshot
|
||||
/// 按指定精度请求当前坐标与地址。
|
||||
func requestSnapshot(desiredAccuracy: CLLocationAccuracy) async throws -> HomeLocationSnapshot
|
||||
/// 按指定精度请求当前坐标。
|
||||
func requestCoordinate(desiredAccuracy: CLLocationAccuracy) async throws -> CLLocationCoordinate2D
|
||||
/// 逆地理编码。
|
||||
@ -24,6 +24,11 @@ protocol LocationProviding: Sendable {
|
||||
}
|
||||
|
||||
extension LocationProviding {
|
||||
/// 请求当前坐标与地址,默认使用最高精度以保持既有业务行为。
|
||||
func requestSnapshot() async throws -> HomeLocationSnapshot {
|
||||
try await requestSnapshot(desiredAccuracy: kCLLocationAccuracyBest)
|
||||
}
|
||||
|
||||
/// 请求当前坐标,默认使用最高精度以保持既有业务行为。
|
||||
func requestCoordinate() async throws -> CLLocationCoordinate2D {
|
||||
try await requestCoordinate(desiredAccuracy: kCLLocationAccuracyBest)
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import CoreLocation
|
||||
import Foundation
|
||||
|
||||
/// 位置上报成功结果。
|
||||
@ -16,6 +17,7 @@ struct LocationReportSuccessResult: Equatable {
|
||||
final class LocationReportService {
|
||||
|
||||
static let operationIntervalMillis: Int64 = 30_000
|
||||
static let manualReportDesiredAccuracy: CLLocationAccuracy = kCLLocationAccuracyHundredMeters
|
||||
|
||||
private(set) var lastOnlineStatusSwitchTime: Int64 = 0
|
||||
private(set) var lastLocationReportTime: Int64 = 0
|
||||
@ -87,7 +89,8 @@ final class LocationReportService {
|
||||
longitude: nil,
|
||||
address: nil,
|
||||
type: 1,
|
||||
showSuccessToast: true
|
||||
showSuccessToast: true,
|
||||
desiredAccuracy: Self.manualReportDesiredAccuracy
|
||||
)
|
||||
}
|
||||
|
||||
@ -98,7 +101,8 @@ final class LocationReportService {
|
||||
longitude: Double?,
|
||||
address: String?,
|
||||
type: Int,
|
||||
showSuccessToast: Bool = true
|
||||
showSuccessToast: Bool = true,
|
||||
desiredAccuracy: CLLocationAccuracy = kCLLocationAccuracyBest
|
||||
) async throws -> LocationReportSuccessResult {
|
||||
if type != 3 {
|
||||
let now = currentTimestampMillis()
|
||||
@ -136,7 +140,7 @@ final class LocationReportService {
|
||||
address: resolvedAddress
|
||||
)
|
||||
} else {
|
||||
snapshot = try await locationProvider.requestSnapshot()
|
||||
snapshot = try await locationProvider.requestSnapshot(desiredAccuracy: desiredAccuracy)
|
||||
}
|
||||
|
||||
let locationText = snapshot.address.isEmpty
|
||||
|
||||
@ -183,7 +183,11 @@ final class HomeViewController: BaseViewController {
|
||||
) as! HomeLocationReportCell
|
||||
cell.cardView.onReportTap = { [weak self] in
|
||||
guard let self else { return }
|
||||
Task { await self.viewModel.manualReportLocation(api: self.homeAPI) }
|
||||
Task { @MainActor in
|
||||
self.showLoading()
|
||||
defer { self.hideLoading() }
|
||||
await self.viewModel.manualReportLocation(api: self.homeAPI)
|
||||
}
|
||||
}
|
||||
cell.apply(
|
||||
address: HomeViewModel.locationReportPromptText,
|
||||
|
||||
@ -67,6 +67,27 @@ final class LocationReportServiceTests: XCTestCase {
|
||||
XCTAssertTrue(stateStore.isOnline)
|
||||
}
|
||||
|
||||
func testManualReportUsesLowerLocationAccuracy() async throws {
|
||||
let reportJSON = """
|
||||
{"code":100000,"msg":"success","data":{"staff_id":"staff-1","expired":0,"status":1}}
|
||||
""".data(using: .utf8)!
|
||||
let api = HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [reportJSON])))
|
||||
let stateStore = HomeLocationStateStore(store: appStore)
|
||||
let locationProvider = MockLocationProvider()
|
||||
let service = LocationReportService(
|
||||
appStore: appStore,
|
||||
locationStateStore: stateStore,
|
||||
locationProvider: locationProvider
|
||||
)
|
||||
|
||||
_ = try await service.manualReport(api: api)
|
||||
|
||||
XCTAssertEqual(
|
||||
locationProvider.requestedSnapshotAccuracies,
|
||||
[LocationReportService.manualReportDesiredAccuracy]
|
||||
)
|
||||
}
|
||||
|
||||
func testTooFrequentManualReportThrows() async throws {
|
||||
let reportJSON = """
|
||||
{"code":100000,"msg":"success","data":{"staff_id":"staff-1","expired":0,"status":1}}
|
||||
|
||||
@ -13,9 +13,11 @@ final class MockLocationProvider: LocationProviding, @unchecked Sendable {
|
||||
var reverseGeocodeResult = "北京市东城区"
|
||||
var requestSnapshotError: Error?
|
||||
var requestCoordinateError: Error?
|
||||
var requestedSnapshotAccuracies: [CLLocationAccuracy] = []
|
||||
var requestedAccuracies: [CLLocationAccuracy] = []
|
||||
|
||||
func requestSnapshot() async throws -> HomeLocationSnapshot {
|
||||
func requestSnapshot(desiredAccuracy: CLLocationAccuracy = kCLLocationAccuracyBest) async throws -> HomeLocationSnapshot {
|
||||
requestedSnapshotAccuracies.append(desiredAccuracy)
|
||||
if let requestSnapshotError { throw requestSnapshotError }
|
||||
return snapshot
|
||||
}
|
||||
|
||||
@ -245,7 +245,7 @@ private final class MockPunchPointLocationProvider: LocationProviding, @unchecke
|
||||
self.reverseAddress = reverseAddress
|
||||
}
|
||||
|
||||
func requestSnapshot() async throws -> HomeLocationSnapshot {
|
||||
func requestSnapshot(desiredAccuracy: CLLocationAccuracy = kCLLocationAccuracyBest) async throws -> HomeLocationSnapshot {
|
||||
snapshot
|
||||
}
|
||||
|
||||
|
||||
@ -1465,7 +1465,7 @@ private final class MockRiskMapLocationProvider: LocationProviding, @unchecked S
|
||||
self.onCoordinateRequest = onCoordinateRequest
|
||||
}
|
||||
|
||||
func requestSnapshot() async throws -> HomeLocationSnapshot {
|
||||
func requestSnapshot(desiredAccuracy: CLLocationAccuracy = kCLLocationAccuracyBest) async throws -> HomeLocationSnapshot {
|
||||
switch result {
|
||||
case .success(let latitude, let longitude):
|
||||
return HomeLocationSnapshot(latitude: latitude, longitude: longitude, address: "测试地址")
|
||||
|
||||
Reference in New Issue
Block a user