Forest、Toggl、OmniFocus、Structured都用过,最后用得最久的反而是系统自带的计时器。不是这些App不好,是用完就完了------那些数字消失在列表里,感觉不到自己在积累什么。
带着这个不满,我做了声境护照:一个把每次专注包装成「出发」的 iOS App,有声景、有里程、有战报卡片。核心问题是:怎么让坚持本身变得值得被记录,甚至被分享。
下面聊三次推翻自己的决定,每次都有点难受,但推翻之后换来的东西我觉得是对的。
第一次推翻:里程任务维度从七个砍到三个
最早设计里程任务系统时,我列了七个维度:完成段数、累计分钟、深度专注次数、连续天数、特定时间段专注、周内完成率、任务完成比例......看起来覆盖全面。
最后砍到三类:sessionCount(完成段数)、focusMinutes(累计分钟)、deepFocusCount(深度专注次数)。
swift
enum ExpeditionMissionKind: String, Codable {
case sessionCount
case focusMinutes
case deepFocusCount
}
struct ExpeditionMissionDefinition: Identifiable, Codable, Equatable {
let id: String
let title: String
let kind: ExpeditionMissionKind
let targetValue: Int
let rewardMiles: Int
}
说一下「深度专注」的判定:连续 25 分钟以上、中途没有切出 App,才算一次 deepFocusCount。没有复杂的中断检测算法,就是这一条规则。
streakDays 本来也在候选里,后来发现它和全局连续打卡逻辑完全重叠------去掉之后刚好三类。这个「三类用户」的判断不是什么严谨调研,是我在早期内测群里发了一个很简陋的问卷,问大家「你觉得自己是哪种专注习惯」,回收了二十几份,粗略分出了喜欢短频快的、偏好长沉浸的、在意质量的三个方向,和这三个维度基本能对上。多了就是噪音,少了又覆盖不到,凑巧。
第二次推翻:ML 方案和五时段分析,全扔掉了
会话结束后给用户推荐「下一次」的时间、时长、声景------这个功能我试了三版。
第一版想用 Core ML 做简单时间序列预测,根据历史专注时段推测用户下次最高效的时间窗口。原型做到一半卡死:新用户没有历史数据,冷启动完全没法用。整个方案扔掉。
第二版换成规则,但规则做复杂了。把一天分成早晨/上午/下午/傍晚/夜间五个时段,分析用户在各时段的完成率和平均时长,生成一段带时段标签的推荐文案。
我找了内测的 8 个用户,用 Screen Recording 录屏后逐个掐表,用户在战报页平均停留不到 4 秒,而这段推荐文案大概需要 6 秒才能读完。时间对不上,文案再准确也是废的。
第三版把规则压缩到三层判断:
swift
func nextActionAdvice(taskCompleted: Bool) -> SessionNextActionAdvice {
let remainingTodayPlan = max(0, store.weeklyPlanTodayTargetSegments
- store.weeklyPlanTodayActualSegments)
let streakHint: String
if store.streakDays >= 5 {
streakHint = "你已连续 \(store.streakDays) 天,重点是稳定复用。"
} else if store.streakDays >= 2 {
streakHint = "再坚持 1-2 天可进入稳定习惯区。"
} else {
streakHint = "建议先连续 3 天完成每日最小闭环。"
}
// 日计划缺口 + 任务状态 + 连续天数,三句话拼完
}
今天计划还差几段、当前任务完没完、连续天数处于哪个阶段------三个判断,输出一两句话。用户扫一眼就走,刚好够用。说白了,「推荐系统」这四个字很容易把自己往复杂方向带,但用户真正需要的可能只是一个不需要思考的下一步提示。
第三次推翻:Demo 数据到底算不算欺骗用户
新用户第一次打开 App,统计页空白,成长页空白,护照里没有任何印记。我做了个有点争议的决定:数据为空时用 StatsService.createDemoFocusLogs() 填充演示数据,界面上标注「示例」。
「有点像造假」------这个疑虑我自己也有。我发了两批内测链接,各 10 人左右,一批是空白状态版,一批是带 Demo 数据版。空白版里大概 2 个人完成第一次专注后还回来用过第二次,Demo 版里差不多 6 个人。样本很小,不算严格测试,但这个差距让我觉得方向是对的。
我猜原因是 Demo 数据让用户在真正开始之前就理解了「完成之后我会看到什么」,降低了对未知的不确定感。标注「示例」是底线,不能省。但空白状态本身也不是什么「诚实」,它只是让用户更快放弃。
附:分享卡片里差点漏掉的小事
用户可以生成三种卡片:单次战报、周回顾、成就徽章。卡片的核心价值是:用户发出去,别人看到,顺手搜一下 App 名字。
有个内测用户截图给我看,说「卡片上的日期格式和你 App 里别的地方不一样」。我才意识到战报卡用的是 yyyy/MM/dd HH:mm,成就徽章用的是 MM/dd/yyyy------就这一个格式不统一,卡片看起来像拼凑的,掉价。统一之后是小事,但没统一之前印象分直接打折。
周回顾的分享文案用 StatsService.buildStatsShareText 动态生成,包含当周里程增量、高峰专注时段、完成段数,每周输出不一样。固定模板发两次用户就能背出来了,不值得。
现在的状态和一个真实困惑
App 刚上线,下载量还在爬坡。三次推翻自己带来了什么,现在看到的结果是:内测阶段第 7 天留存从最早版本的大概 15% 爬到了 40% 出头,不算亮眼,但每次推翻之后都能往上走一点,这让我觉得这些决定没白费。鸿蒙版在做,雷达界面可以拖拽「音效球」混音调声场,ArkTS 的手势处理比 UIKit 繁琐不少,但逼出了一个新交互,反倒成了差异点。
三次推翻都是我自己逼自己,复盘时看数据、看录屏、发问卷------但我知道自己的盲区越来越大,靠自己否定自己能走的路越来越短。现在需要外力了。如果你做过工具类 App,怎么找到愿意认真挑毛病的那批用户的?鼓励听着舒服,但对改产品帮助不大,这事儿我有点卡。