
很多时候,真正让人困扰的不是"记不住几点吃药",而是过了一会儿又开始想:我刚刚到底吃没吃?
因此我做了「按时吃药·服药提醒」。它是一款 iPhone 用药计划、提醒与记录工具:不提供诊疗建议,也不替代医生或药师;它只负责把每天的计划、提醒和记录整理清楚。
这篇文章既介绍产品,也记录一下它在 iOS 端的实现思路。
想解决的,不只是一个闹钟
系统闹钟当然能提醒时间,但它解决不了这些日常问题:
- 今天还有哪些待服?
- 这一剂已经完成、跳过,还是错过了?
- 昨天有没有按计划完成?
- 不打开 App 时,能否快速确认下一剂?
所以这个 App 的核心不是"响一次通知",而是围绕每一剂用药形成一个清晰的状态闭环:计划 → 提醒 → 确认 → 记录 → 回看。
1. 首页:今天该做什么,一眼知道
首页把当天的用药项目聚合在一起,展示待服、已服、已跳过和已错过数量,并给出当天完成进度。用户不必在多层页面之间寻找当前要处理的事项。

每一剂可以标记为已服用或跳过;完成后,状态会同步影响历史记录、通知安排和桌面组件显示。
2. 用药计划:按自己的时间安排
不同的用药安排不适合被硬塞进同一种固定频率。创建计划时,可以设置每次剂量、频率、服药时机、多个提醒时间和计划周期。

对实现来说,计划不是一条静态文本,而是用于生成每日服药实例的规则。这样,某一天的每一剂都有独立状态,用户也可以只处理其中某一剂,而不会影响其他时间点。
3. 历史记录:不再反复猜"吃没吃过"
完成、迟服、跳过等状态会保留在历史中。回看时,可以按日期查看当天进度和具体时间线。

这也是我认为用药提醒和普通待办事项最大的差异:用户需要的不只是"提醒已弹出",还需要一个可以确认和追溯的记录。
4. 桌面组件:不用打开 App 也能确认
桌面组件只做"下一步信息"的展示:下一剂、错过提醒和当天进度。完整处理仍在 App 中完成,避免把小组件做成复杂的操作界面。

技术实现:保持简单的本地优先架构
项目采用 SwiftUI + GRDB(SQLite),最低支持 iOS 16.6。整体数据流保持单向:
text
Models(GRDB 数据模型)
↓
AppStore(全局状态与业务入口)
↓
Views(SwiftUI 界面)
我没有额外拆出独立 ViewModel 层。对这个以本地数据和交互状态为主的 App 来说,AppStore 负责加载、更新和发布状态,界面通过 @EnvironmentObject 读取即可,结构会更直接。
几个关键实现点:
- 本地存储:药品、计划和服药记录使用 GRDB 管理;UUID、日期和数组都转换为适合 SQLite 持久化的字段。
- 状态驱动:首页、历史记录和组件都从同一份服药记录状态推导展示,避免多处重复计算。
- 本地通知:按具体服药实例安排近未来通知;主通知优先,重复提醒有明确时间边界。
- 桌面组件:主 App 将当天数据写入 App Group,小组件不直接访问 SQLite;组件按时间线派生"待服/已错过/已完成"等状态。
- 隐私边界:核心数据保存在本机;健康用药导入为用户主动发起的只读能力,不向健康 App 写入或修改数据。
目前功能
- 药箱与有效期管理
- 多频率、多时间点的用药计划
- 本地提醒与重复提醒
- 已服、迟服、补服、跳过、错过等记录状态
- 按日期回看的历史记录
- 小、中、大三种桌面组件
- 字体缩放与隐私政策入口
这款 App 适合谁?
如果你需要给自己或家人整理用药时间,或者经常要确认"今天有没有完成",它可以作为一个轻量的计划与记录工具。
App Store 搜索:按时吃药·服药提醒
也可以直接打开:App Store 下载页
本 App 用于用药计划与记录管理,不替代医生、药师的专业诊疗建议。具体用药、剂量和调整请遵医嘱或咨询专业人士。