后台定位太耗电的问题,我用 significant location change 解决了 90%

4 阅读3分钟

起因:翻相册找不到去年走过哪些路

上周翻相册找一张去年在成都拍的照片,翻了十分钟没找到,但脑子里冒出来的问题其实不是照片本身——我那次到底走了哪些街?住的酒店在哪个方向?后来去的那个苍蝇馆子离春熙路多远?

相册回答不了这些问题,高德的足迹功能藏得很深,数据还不完整。我想要的东西很明确:一张地图,上面是我去过的所有地方。没有别的。

所以我做了一个 iOS App,叫「雁过留痕」。后台自动记录轨迹,画在地图上,完事。没有社交,没有分享广场,没有配速心率,打开就是地图和你的痕迹。

最难啃的骨头:后台定位的电量问题

独立开发,从去年十一月开始写,到现在大半年。中间最纠结的就是耗电。

持续定位非常吃电量,我前后试了好几套方案。最早用 CLLocationManager 的 startUpdatingLocation 保持常驻,一天下来电量肉眼可见地掉。后来尝试降低 desiredAccuracy 到 hundred meters 级别,省电了但轨迹断断续续不成形。

最终方案是系统级的 significant location change 配合间歇性精确定位:

// 基础监听:基站/WiFi级别变化时唤醒
locationManager.startMonitoringSignificantLocationChanges()

// 唤醒后开启短时精确定位,拿到坐标后立即关闭
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    manager.desiredAccuracy = kCLLocationAccuracyBest
    manager.startUpdatingLocation()
    // 拿到满足精度的点后停止,写入本地数据库
    DispatchQueue.main.asyncAfter(deadline: .now() + 8) {
        manager.stopUpdatingLocation()
    }
}

这套方案跑下来,日常使用基本感知不到额外耗电。精度上有一点牺牲,不会像运动手表那样米级记录,但对于「我去没去过这个地方」这个问题,够用了。

数据存储的取舍:全部本地,不出手机

另一个我做的比较绝的决定是数据全部存本地。轨迹数据本质上是一个人所有行踪的集合,这东西的敏感程度不用多说。我知道加 iCloud 同步换机方便,但第一版我想把隐私做到最干净——轨迹数据不出手机。

后续如果大家确实需要多设备同步,再考虑端到端加密的方案,但那是下一步的事了。

定位:只做留痕,不做运动

开发过程中有朋友建议加配速、加运动模式,我都拒绝了。这个 App 解决的问题只有一个:记录你去过的地方。跑步数据、心率曲线,那是另一个品类的事情,市面上已经有很成熟的产品了。

我更想做的是那种你半年后打开,看到地图上密密麻麻的点,然后想起「哦原来我去过这里」的感觉。雁过留痕,字面意思。

现在的状态

App Store 已经上架了。想问问各位做独立开发的同行一个问题:这种纯记录型的工具,你们觉得一次性买断和按年订阅哪个模式更合理?我自己倾向买断,但还在犹豫,想听听不同角度的看法。