用 Screen Time API 算出每笔订阅的单次使用成本

起因:信用卡账单里那串自动扣款

上个月账单日,我对着 847 块的订阅扣款明细数了一遍:Notion、Figma、ChatGPT Plus、iCloud 200G、YouTube Premium、Spotify、某个健身 App、某个冥想 App。数完之后打开手机翻了翻,其中至少三个已经超过两周没打开过了。

作为一个独立开发者,记账不是我的痛点,我清楚钱花在哪了。真正困扰我的是没有一个量化指标来判断"值不值"。我能感觉到有些订阅在吃灰,但"感觉"这个东西太模糊了,不足以让我果断点下取消续订。

所以我给自己写了个工具,核心公式就一行:订阅费用 ÷ 实际使用次数 = 单次使用成本。当某个 App 每打开一次的成本比打车去图书馆还贵,那确实该砍了。这就是「订阅斩」的由来。

产品思路

目标用户画像很具体:订阅了 5 个以上 SaaS/App 服务,月固定支出 200-1000 元区间,想把"好像不太用"变成"数据证明确实不需要"的年轻上班族。它不是记账工具,也不是续费提醒闹钟。

功能分三块:账单日历加多档到期提醒(防止静默扣费)、Screen Time 打卡计算使用成本、AI 顾问给出砍/留/降级建议和平替推荐。

技术实现:Screen Time 数据获取踩坑

这部分是整个项目里最折腾的环节,值得单独展开说说。

iOS 的 Screen Time 数据获取远没有想象中方便。Apple 在 iOS 16 之后开放了 DeviceActivityReport 这个 framework,但它的设计初衷是家长监控(Family Controls),拿来做个人用途限制不少。我最终选择的方案是通过 DeviceActivityMonitor 注册一个 Extension,在用户授权 Family Controls 之后监听目标 App 的使用时段。核心代码大致如下:

import DeviceActivity
import ManagedSettings

class SubscriptionMonitor: DeviceActivityMonitor {
    override func intervalDidStart(for activity: DeviceActivityName) {
        let store = UserDefaultsStore.shared
        store.markSessionStart(activity: activity.rawValue, at: Date())
    }
    
    override func intervalDidEnd(for activity: DeviceActivityName) {
        let store = UserDefaultsStore.shared
        store.markSessionEnd(activity: activity.rawValue, at: Date())
        CostEngine.recalculate(for: activity.rawValue)
    }
}

这里有一个血泪教训:DeviceActivityMonitor 跑在独立的 Extension 进程里,和主 App 不共享内存。我最终用 App Group + UserDefaults suite 做数据同步,没上 CoreData,因为写入频率不高且数据结构简单。如果你也在做类似的事情,一定要先确认 entitlements 配置正确。这个 Extension 有个很恶心的特点——配置出错时会静默失败,没有任何报错日志,排查起来极其痛苦,我在这上面浪费了大半天。

几个设计决策

拿到原始使用数据之后,还有几个需要人为定义的点。

"使用一次"怎么算?我的规则是同一个 App 在 30 分钟内的多次前后台切换只计一次。这个阈值是我根据自己的使用习惯拍的,后续会开放用户自定义。

账单周期怎么对齐?有些订阅按月扣,有些按年扣。年付的我会折算成月均成本再除以当月使用次数,保证横向比较时口径一致。

AI 顾问

这部分接了 OpenAI 的 API,把用户的订阅列表、使用频率、费用数据打包成 prompt,让模型输出三类建议:继续保留、降级到免费版/低价档、直接取消并推荐平替。推荐平替这个功能用户反馈很好,比如有人通过它发现 Notion 的轻度使用完全可以用 Apple 备忘录加快捷指令替代,每月省下 96 块。

实际效果

我自己用了两个月,月订阅支出从 847 降到了 412。砍掉了三个几乎不用的服务,两个从付费降级到免费版。体感上没有任何损失,因为数据已经告诉我那些东西确实没在用。

如果你也被订阅账单困扰,可以在 App Store 搜索「订阅斩」试试。技术实现上有任何问题欢迎评论区交流,尤其是 DeviceActivity 相关的坑,踩过的人应该不少。

posted @ 2026-08-11 16:45  samexxx  阅读(6)  评论(0)    收藏  举报