起因
跑了大半年步,打开各种记录 App 一看,全是线条。今天 5 公里,昨天 3 公里,一条一条的轨迹躺在那里,但我完全没有"我到底探索了这座城市多少"的感觉。
线条是瞬时的,跑完就结束了。我想要一个东西能告诉我:你这大半年,实实在在踩过了多少土地?
所以去年开始做「雁过留痕」。核心机制就一句话:把你走过的路转化成探索面积(km²),像开荒一样,一格一格地把城市空白填满。
25m 网格是怎么定下来的
做法是把地图切成 25m × 25m 的格子。GPS 轨迹经过一个格子,它就永久标记为"已探索"。所有点亮的格子面积累加,就是你的数字。
25m 这个数是试出来的,试了三轮:
- 10m:太细了,GPS 漂移严重,站着不动都能"探索"出一片区域,数据失真
- 50m:太粗,走过一条窄巷子根本不会点亮新格子,用户感知不到变化
- 25m:刚好能区分"走了这条街"和"走了隔壁那条街"
有个细节容易忽略——25m 网格在不同纬度下实际物理面积是不一样的,经度 1 度的距离随纬度变化。国内这个范围(北纬 18°-53°)误差我算过在 ±7% 以内,可以接受。全球精确的话得上等面积投影,以后再说。
成就系统怎么拆的
技术上我用 BadgeMetrics 把所有维度的统计数据聚合在一起,每次轨迹段写入后重新 build:
struct BadgeMetrics {
let totalDistanceKilometers: Double
let totalDurationHours: Double
let recordedDays: Int
let currentStreakDays: Int
let chinaProvinceCount: Int
let chinaAreaKm2: Double
let cityUnlockCount: Int
let globalAreaKm2: Double
// ...
}
成就路线拆成了五条独立的 Track:
enum BadgeTrack: String, CaseIterable {
case exploration // 探索面积
case consistency // 连续打卡
case china // 省份/城市解锁
case world // 国家解锁
case pro // 付费会员专属
}
这样拆开之后新增一条成就线只要加一个 case + 对应的 Series 数组,完全不碰其他代码。去年底加 china 那条线时(内置了完整中国行政区边界 + GCJ-02 偏移适配),主体逻辑改动不超过 30 行。
world 这条线说实话做早了,目前用户基本在国内活动,但架构上留着不亏。
后台 GPS 这个老大难
轨迹 App 绕不过后台定位。iOS 管控越来越严,每个大版本都得回归测试。
我的策略:前台高频采点(每秒),切后台后降到显著位置变化才唤醒。轨迹段(segment)按时间间隔自动分割——两点之间超过 5 分钟没新数据就切一段。
配合 pausesLocationUpdatesAutomatically 让系统在用户静止时自动暂停,实测一次 2 小时 citywalk 额外消耗 8-12% 电量,静止暂停能再省 3% 左右。
坑在哪呢?pausesLocationUpdatesAutomatically 暂停后恢复的时机不可控,偶尔会丢一小段轨迹。我加了一个补偿逻辑:恢复时如果发现距离上个点超过 100m,就插入一段线性插值,至少让面积计算不会出现明显漏洞。这个方案不完美,但比留一个大窟窿强。
数据备份——被用户教训出来的
轨迹数据不可再生,你没办法重走过去三个月的路。
这个道理我当然知道,但一开始还是偷懒只做了本地存储。直到有个用户换手机后发现数据全没了,来评论区问怎么办。那之后我花了一周做了两件事:
- 自定义文档类型
.wingprintBackup(基于 JSON),支持系统分享面板导出/导入 - 支持 GPX 格式导出,兼容其他轨迹 App
教训就是:涉及用户不可再生数据的功能,备份不是"以后做",是 Day 1 就该做的。
目前的困境
说实话数据不好看。App Store 评分 5 分(样本很小),最近一周下载接近零。
我觉得核心问题是冷启动体验。这类 App 需要用户坚持一两周才能感受到面积增长的成就感,但大部分人第一天打开,地图上空空的,没有任何正反馈就走了。
试过一个方案:引导用户授权"始终定位"后,拉取系统的"重要地点"历史数据来预填一部分探索区域。效果一般——iOS 的重要地点数据精度很粗,填出来的面积和实际体感差很远,反而让用户困惑。
目前在做的是桌面 Widget,让用户不打开 App 就能看到今天新增了多少面积,降低日活门槛。但我不确定这够不够。
冷启动怎么做才能让用户第一天就有获得感? 我想了几个方向但都不太满意——导入跑步 App 历史 GPX?给新用户一个"探索你家方圆 1km"的新手任务?如果你做过类似留存设计,很想听听思路。
App Store 搜「雁过留痕」能找到,ID 是 6759516186,有兴趣可以看看实际效果。