示例代码均为匿名化改写,用于说明模式;距离阈值应由产品规则定义。
设备位置和用户地址不是一回事
附近推荐需要设备定位,但用户也可能手动选择目标地点。位置状态应同时记录地区信息和选择来源,让自动定位更新不会覆盖用户主动选定的地点。
首页刷新规则可以拆成三部分:首次取得有效位置时刷新;地区发生变化时刷新;自动定位只有移动达到业务阈值才刷新。用户手动选择则可以绕过自动移动阈值,相同地址仍无需重复请求。
enum LocationSource: Sendable {
case automatic
case manual
}
struct Coordinate: Equatable, Sendable {
let latitude: Double
let longitude: Double
}
enum HomeRefreshPolicy {
static func shouldRefresh(
from previous: Coordinate?,
to next: Coordinate,
source: LocationSource,
distance: (Coordinate, Coordinate) -> Double,
thresholdMeters: Double
) -> Bool {
guard let previous else { return true }
guard previous != next else { return false }
if case .manual = source { return true }
return distance(previous, next) >= thresholdMeters
}
}
用户手动选择地点后,应明确由该选择优先,直到用户主动请求重新定位。自动定位还要考虑 horizontalAccuracy:精度较差时,不能只用原始坐标差触发刷新,可结合准确度或稳定区域规则抑制漂移。
单飞加载与旧内容保留
首页模型可以用请求标识保证一次只运行一个加载循环。请求期间若位置变化,旧地区的响应不应直接替换页面快照;加载完成前再次对比当前地区,必要时对新地区发起下一次请求。
已有首页快照时,刷新应保留原内容,避免重新显示首次加载骨架。请求失败也要检查地区是否已经变化,防止把旧地区的网络错误展示为当前地址的错误。
如何测试定位策略
距离和地区决策可以抽成纯规则函数,用固定坐标覆盖首次定位、轻微漂移、跨地区移动、定位失败和手动选址等场景。这样无需触发系统权限弹窗,也能稳定验证产品策略。
精确坐标属于敏感信息。请求、隐私说明和日志保存策略应相互匹配,调试日志不能因为方便排障而长期保留原始位置。
