WaterDiary 喝水记录 App 实战(1)· 创建项目与真机运行
前段时间研究过一个问题:在 Windows 上,能不能用 HBuilderX 做出 SwiftUI 原生界面? 当时我尝试的是 uni-app + UTS + SwiftUI 的混合方案,相关思路也写在了之前那篇 HBuilderX 文章里。
那种方式能把 JS 业务和原生界面结合起来,但要是只想写一个完全用 SwiftUI 开发的小 App,就显得有点绕了。除了 Swift 代码,还得考虑 UTS 插件、JS 与原生通信,以及自定义基座等问题。一个简单的原生页面,前后要处理的东西并不少。
最近发现了一个工具叫 KXBuild 。它能在 Windows 上直接创建标准的 SwiftUI 工程,写的就是 Swift 代码,不用为了显示一个原生页面先搭一层 JS/UTS。于是我准备换个方式,重新做一个简单的喝水记录 App,项目叫 WaterDiary。
这次我在 Windows + VS Code + WSL Ubuntu 环境中创建工程,并把默认页面运行到了 iPhone 上。KXBuild 的安装与环境配置会另外写一篇,这里不展开。
为什么这次改用 KXBuild?
这里不是说 HBuilderX 不能做原生功能。前面那套混合方案也有适用场景,比如项目已经有 Vue/JS 业务,又希望部分界面使用 SwiftUI。只是对于从零开始的纯原生项目,开发路径不一样。
拿我之前研究的方案和这次的操作对比一下:
| 之前的 HBuilderX 混合方案 | 这次的 KXBuild 原生方案 | |
|---|---|---|
| 项目入口 | uni-app / JS 业务工程 | SwiftUI App 工程 |
| 原生页面 | 通过 UTS 等方式调用 Swift | 直接编写 SwiftUI View |
| JS 与原生通信 | 需要设计调用和事件回传 | 纯 SwiftUI 项目不需要这层通信 |
| 工程结构 | 混合工程与原生插件 | 直接生成 .xcodeproj |
| 真机运行 | 需处理对应混合开发流程 | 在 KXBuild 中选设备并构建调试 |
对我来说,最大的区别不是少点了几次按钮,而是终于可以把注意力放在 SwiftUI 本身:页面怎么布局、状态怎么管理、数据怎么保存,不用同时维护一套 JS 与 Swift 的通信代码。
当然,开发环境、iOS SDK、签名证书和真机连接仍然要配置好。KXBuild 并不是把这些 iOS 开发的基本要求都取消了。
下面进入实际操作。走通:创建 SwiftUI 工程 → 连接 iPhone → 运行默认页面。
1. 使用什么开发环境?
平时看到的 SwiftUI 教程,大多都是从 macOS 上打开 Xcode 开始的。而这次使用的是 Windows,编辑器和工程构建都放在 KXBuild 这套流程中。
根据 KXBuild 官网 的介绍,它可以在 Windows、Linux、macOS 上处理 SwiftUI、UIKit 等 iOS 工程,并通过 VS Code 插件创建项目、构建和进行真机调试。
写这篇时,KXBuild 仍处于注册测试阶段。本文默认你已经完成安装、工具链配置,并且可以在 VS Code 中看到 KXBuild 侧边栏。还没有完成这些准备的,可以等后续单独的安装教程。
这次截图中的环境是:
| 项目 | 本次使用的环境 |
|---|---|
| 电脑系统 | Windows |
| 编辑器 | VS Code |
| 开发环境 | WSL Ubuntu + KXBuild |
| 开发语言 / UI | Swift + SwiftUI |
| 示例项目名 | WaterDiary |
| 工程类型 | iOS 应用(SwiftUI) |
| 调试设备 | iPhone SE(第 3 代),USB 连接(截图显示 iOS 27.0) |
这里要注意:KXBuild 不是 iOS 模拟器。按照官网说明,Windows 端需要连接 iPhone 真机进行运行和调试;如果暂时没有 iPhone,可以先创建工程、编写代码,但不要把“编译通过”和“已经能在手机上运行”当作一回事。
2. 新建 SwiftUI 项目
环境准备好后,打开 VS Code,在 KXBuild 侧边栏中点击右上角的 ...,选择 KXBuild: 新建项目。
也可以按 Ctrl + Shift + P 打开命令面板,搜索 KXBuild: 新建项目。
接着会进入一个分步向导。
第一步:选择项目模板
模板列表中有 SwiftUI、Swift + UIKit、Objective-C、WebView 等类型。这里选择 iOS 应用(SwiftUI) 。
这里我直接选 SwiftUI 模板。之前在 HBuilderX 方案里,我还要考虑原生插件放在哪、如何让 JS 调用它;这次新建完就是原生工程,刚好适合做这种小型练手项目。
第二步:填写项目名称
项目名填写:
WaterDiary
这里使用英文项目名会比较方便。这个名字会用于生成项目和相关 target,后面如果要把 App 的桌面显示名称改成中文,可以单独设置,不必在创建工程时就写中文。
第三步:设置 Bundle Identifier
接下来填写 Bundle Identifier,也就是 App 的唯一标识符。
截图中我填写的是:
so.phonegame.waterdiary
它采用反向域名的写法。你自己创建时不要直接照抄,换成属于自己的标识即可,例如:
com.yourname.waterdiary
Bundle Identifier 后面和签名、描述文件、安装到手机上的 App 身份都有关系,尽量一开始就确定好;如果以后做多个示例 App,也不要让它们共用同一个标识。
第四步:选择保存目录
向导最后还会让我们选择项目目录。选择一个方便管理的文件夹,确认后等待工程创建完成。
这一步我没有单独截图。创建完成后,左侧 KXBuild 面板中已经可以看到 WaterDiary.xcodeproj、App target 和 Assets.xcassets 等资源,说明工程已经生成并被识别。
到这里,一个最基础的 SwiftUI 工程就有了。尤其是看到 WaterDiary.xcodeproj 出现在侧边栏时,和之前的 uni-app 混合工程相比,整个结构直观了不少。
3. 连接 iPhone 并选择调试设备
下一步是我觉得最关键的一步:真机运行。
先用 USB 数据线把 iPhone 连接到 Windows 电脑。第一次连接时,一般需要确认以下事项:
- Windows 上已安装并打开 Apple Devices(「Apple 设备」),让电脑能够识别手机;
- 在 iPhone 上选择「信任此电脑」;
- 在 iPhone 的「设置 → 隐私与安全性」中开启开发者模式;
- 准备与 App 标识和设备匹配的开发签名证书、描述文件。
回到 VS Code,在 KXBuild 设备选择列表中找到自己的 iPhone。截图里可以看到同一台 SE3 的 USB 和 Wi-Fi 连接方式,我选择了 SE3 USB。
建议首次调试优先使用 USB,连接相对直接,遇到设备识别问题也更容易排查。
选中设备后,确认构建配置为 Debug,然后按 F5 启动调试。按照 KXBuild 的工作流程,它会执行构建、签名、安装、启动和调试器附加等步骤。
如果中途出现签名错误,优先检查 .p12 证书、.mobileprovision 描述文件以及设备 UDID 是否匹配;如果设备列表为空,先回到 Windows 检查数据线、手机信任状态和 Apple Devices。
4. 真机运行效果
完成上面的操作后,我在 iPhone 上看到了模板自带的 SwiftUI 页面:
页面中间显示的是 Hello, WaterDiary!,下面还有一个蓝色的 Tap me 按钮。
现在当然还谈不上一个真正的喝水记录 App,它只是新建模板的默认界面。不过能在手机上看到它,至少说明这次的工程创建、构建和真机安装运行流程已经走通了。
这一点也是我这次感受最明显的地方:从新建模板到手机显示 SwiftUI 页面,不需要先写一个 Vue 页面做容器,也没有经过 UTS 调用链。 对于只想做原生 iOS App 的场景,这样写起来确实更直接。
后面再修改 SwiftUI 页面时,就可以基于这个工程逐步开发,而不是每写一点代码都先折腾环境。
5. 我遇到问题时会先检查什么?
这次的截图展示的是成功结果。为了方便以后自己查,也把几个容易混淆的环节记下来:
| 现象 | 先检查什么 |
|---|---|
| 工程创建后没有出现在侧边栏 | 是否打开了包含 .xcodeproj 的工程目录 |
| 设备列表里没有 iPhone | 数据线、Apple Devices、手机解锁和「信任此电脑」 |
| iPhone 上无法启动 App | 开发者模式、开发证书、描述文件和 Bundle Identifier |
| 第一次调试等待时间较长 | 查看 KXBuild 输出和通知,确认是否在准备设备符号等文件 |
| 编译错误不知道在哪里看 | VS Code 的「问题」面板,以及「输出」中的 KXBuild 相关日志 |
另外,官网明确说明 KXBuild 不提供 iOS 模拟器。如果你是跟着本文在 Windows 上操作,测试环节要提前准备真机。
整体下来,这次最重要的结果很简单:WaterDiary 已经作为一个纯 SwiftUI 工程在 iPhone 上跑起来了。 对于这样一个从零开始的小项目,直接创建原生工程确实比我之前研究的 JS/UTS 混合方案更省事。签名和真机环境还是要准备,但至少这次不用再为一个 SwiftUI 页面额外搭通信层了。
参考资料