# Hearth 开发日记：一个智能家居中控的从 0 到 1

# TL;DR

我用 Swift + SwiftUI 写了一个 iPad 智能家居中控 App，核心解决一个问题：**比旋钮和语音更方便地控制灯光**。这是一套完全基于个人需求、非常"自我"的实现，文章记录了从灵感诞生到踩坑落地的全过程。

---

## 起源：一面墙引发的思考

早在装修新家之前，我就盯上了 iPad 上墙这个「行为艺术」。

市面上的解决方案大多搭配小米平板控制米家设备。但作为多年果粉，我对 HomeKit 和 Matter 的大一统有种莫名的迷信，于是装修时选择了 **Aqara 全屋 + Matter 单品** 的方案——这也意味着我的上墙方案只能用 iPad。

我在客餐厅边上的墙体留了一处 86 底盒，从旁边的智能开关并联取电，给磁吸墙充供电，加上魔改磁吸壳，把一台闲置的 iPad Pro 改成了磁吸充电的形式。

装修入住后，一套「手扶拖拉机」般的方案诞生了：
- 引导式访问把 Apple 家庭固定在主屏
- 隔壁 Aqara 面板的接近感应 + Matter 桥接，人靠近时给 iPad 上的 HA 发通知点亮屏幕
- 实现「我来 → 我开关灯 → 我离开」的简单逻辑

但很快发现问题：**绝大多数智能家居控制通过语音或自动化完成**，真正需要靠近 iPad 操作的情况，用隔壁面板直接点按反而更方便。

如果需要整体调节客餐厅亮度，语音没那么方便，我会用 Aqara 旋钮 V1 加上预设好的灯组直接转动——但这个旋钮也有局限，比如进度 100% 时顺时针转没法改变灯光状态，需要先点按开灯再旋转（此处 @Aqara）。

## 转折点：Vibe Coding

入住半年后，转机出现——**Vibe Coding** 火了。

看着大量非专业开发者用 AI 把想法变成现实，我心里痒痒的。作为多年全栈开发，虽然没什么原生 iOS 经验，但抱着对 Swift 的憧憬，我敲下了第一行 Prompt。

### 核心功能

开门见山，这个 App 就做三件事：

1. **快速调节 Apple 家庭某一空间的亮度/温度/窗帘开合度**
2. **全天候显示日期时间**（给 iPad 这类没有 AOD 的设备强行实现）
3. **绑定二元传感器实现人来亮屏**

这款 App 是完全基于自身需求出发、非常「自我」的一套实现，希望能吸引到有相同需求、相同脑回路的智能家居玩家。

## 技术选型：为什么不用 React Native？

很多人问：你跨平台经验那么丰富，为什么不用 RN？

答案很简单：**HomeKit 仅支持 iOS**，而且 HomeKit 相关的开源库年久失修。与其在跨平台框架里折腾原生桥接，不如直接上手 Swift。

最终选择 **Swift + SwiftUI**：
- 上手快，AI 生成的代码我能直接阅读
- SwiftUI 声明式 UI 接近我熟悉的 Flutter 经验
- 出于对开发效率和代码质量的考虑，选择了自己更能接受的技术栈

AI 工具方面没有特别偏好：Cursor → Claude Code → Gemini，甚至 CodeX 和 OpenCode 都用过。

## 踩坑记录

### 1. Swift 版本地狱

AI 大模型训练素材主要是开源大户，Swift 作为苹果闭源语言，知识储备明显不足。

典型例子：AI 不清楚我用的是 Swift 6 和 iOS 26，经常引用 deprecated 接口。最搞笑的是 Gemini 3 刚接入时，坚称我代码里的 iOS 26 是 typo，要给我改成 17。

**解决**：在 agent 文档里写清楚版本约束，配合 Context7 这类 MCP 查询最新文档。

### 2. HomeKit 协议坑

滑动调节房间亮度时，总有一组灯带不受控制。让 AI 单独 debug，它很容易把自己绕进去。

后来深入了解协议才知道：设备下面还分「服务」，对应物理设备上的「回路」。最早只把指令发到灯带上，实际只控制了每个驱动的第一个回路。应该下发到服务上才能实现预期效果。

**感悟**：把原因描述清楚后，AI 很快就能修复问题。人类的领域知识仍然关键。

### 3. 手势交互的调试地狱

这部分大概率受限于我的表达能力，AI 产出的结果总不能令我满意，微调起来也很麻烦，半人工半自动改了很久。

另外，最初本着 MVP 原则对数据结构做了很多简化，导致 Xcode 里的 Canvas 预览工具没能充分利用——几乎所有组件都直接依赖 HomeKit SDK，很难 mock。最后专门分了精力做依赖封装和抽象，才让关键组件的预览可以 mock 家庭实例。

### 4. Swift Concurrency

对于之前 JS 经验为主的我来说十分陌生（上学学的早就生疏了），这里只能劝自己相信 AI，至少目前为止还没出严重问题。

## App 里的小设计

### 人来亮屏

受很多大佬启发，原型是通过传感器触发点亮屏幕，在 App 里变成了直接监听指定传感器状态，除了传感器外没有其他第三方依赖。

### 交互

结合「人来亮屏」，只需抬手一划就能将空间内的灯开到想要的亮度，比旋钮更直观。

### 自适应外观

不同于传统的「暗黑模式跟随系统」，App 里有一个「自适应」选项，根据当前房间背景图片的「明度」自动选择明暗外观，确保文字可读性。

### 设备、房间筛选

虽然希望一次操作控制所有灯，但难免有例外。用户可以在房间设置里取消勾选对应设备，或在制冷、制热季节分别勾选空调、地暖设备。

另外，针对卫生间、储藏间等琐碎空间，用户也可以选择隐藏。我自己就只在 App 里显示客餐厅、阳台、走廊这样的公区可调光空间。

## 名字的故事

App 最初叫「WallFlow」，是起项目时 AI 自己取的，主要因为早期 Prompt 过度强调了「上墙」属性。

经过多番深入交流，定了一个更贴切的名字 **「Hearth」（壁炉）**。考虑到中式家庭和很多现代家庭不再配置壁炉，就算有也是假的，希望这个 App 能像最早的壁炉一样给家庭带来温暖和便利。

中文名还没想好。

## AI 编程工具链总结

### Cursor

最早用的 AI 编辑器，tab tab 的体验记忆犹新。后来出了 Agent 模式也用了一段时间。自动模式下处理文档还可以，实际上手开发时需要手动指定 Claude Sonnet 才有理想效果，去年订阅到期后没再续了。

### Claude Code

一开始用 CC 加 Kimi-k2，后来发现 token 烧得挺快，转而订阅。目前用下来是当之无愧的王者，Claude 一直在引领 AI 编程的方向。

最大的问题是用量——5 小时限制卡得死死的，到了就得歇，要不就继续氪金，每周也有上限。开多个项目基本不够用，得开 5x。

### CodeX + Kimi-k2

早期跟风用来做 Code Review，确实发现了不少问题。后来更新后需要重新配置 API，懒得折腾，没再用了。

### Gemini 3

后起之秀，最近刚开了一年 Gemini Pro。目前体验非常好，但不太稳定，有时会陷入循环或报错。

好处是用量很慷慨，按天设上限，用完了还能回退到 Gemini 2.5 flash。此处继续吐槽 Claude Code 五小时上限简直反人类，经常激情编程时戛然而止。

### SpecKit

除了 AI 工具外，也用了一些其他工具确保产出可控，首当其冲的是 SpecKit。通过「宪章」确定项目基础（编程风格、技术选型等），减少 Code Smell。其次将每个功能模块以 Spec 形式定义，从需求描述到任务划分、验收标准，框死开发内容。

实际开发大型模块时有一定帮助，小改动反而浪费。目前被 Claude Code 的 plan 模式取代——先用 Opus 指定计划，再交给 Gemini 实现，是我现在比较接受的模式。

---

从第一次接触 GitHub Copilot 和 Cursor，到现在 Agent 模式为主，AI 编程已经发生巨大变化。相信再过几个月，我的工作模式又会大相径庭，就像现在的 Vibe Coding 之于之前的 Tab Tab。

这个项目还有大量手动干预，一方面是在熟悉 Vibe Coding 流程，另一方面也是想借此机会上手憧憬已久的 Swift。基于这个体验，后续可能还是会走向更激进的 AI 编程之路。
