基于 STM32F405VGT6 的无线血氧双波长(660 nm / 940 nm)监测系统 —— iOS 上位机(SwiftUI)
本仓库是 SpO2-Wireless-Android 的 iOS 重写版,沿用同一套硬件协议(STM32F405VGT6 + ESP8266 SoftAP,10 字节定长帧,660nm/940nm 双波长 DC/AC 四通道),界面采用 SwiftUI + Apple Human Interface Guidelines 重新设计,原生适配 iPhone 与 iPad。
本仓库只包含 iOS 客户端源码,不含 STM32 固件与硬件原理图。硬件与通信协议与 Android 版完全一致,可参考 SpO2-Wireless-Android 的协议说明。
- 四路实时波形:660nm / 940nm 的直流分量(DC)与交流分量(AC),使用 SwiftUI
Canvas原生绘制,带网格背景与扫描游标。 - 自适应布局:
- iPhone:
NavigationStack单栏导航,波形卡片纵向堆叠。 - iPad:
NavigationSplitView侧边栏 + 详情双栏布局,波形卡片以 2 列网格展示,充分利用大屏空间。
- iPhone:
- 可配置无线连接:原生
Form/LabeledContent输入 IP 与端口,IPv4 格式与端口范围(1-65535)校验,通过UserDefaults持久化并自动回填。 - 健壮的 TCP 接收:基于
Networkframework 的NWConnection,使用receive(minimumIncompleteLength:maximumLength:)精确读取 10 字节定长帧,等价于"readFully",正确处理连接断开。 - 连接状态可视化:状态点 + 文字(未连接 / 连接中 / 已连接 / 连接失败),开始/停止按钮控制连接生命周期,离开页面自动断开。
- 深色模式 / 动态字体:全部使用系统语义颜色与字体,自动适配深色模式与无障碍字号。
- 零第三方依赖:纯 SwiftUI + Network framework + Foundation。
| 实时监测(iPhone) | 无线连接(iPhone) | 关于(iPhone) |
|---|---|---|
![]() |
![]() |
![]() |
实时监测(iPad,NavigationSplitView 双栏布局)
配色延续 Android 版的医疗科技风格:深青绿主色(BrandPrimary)+ 660nm 红 / 940nm 蓝双波形配色,状态色采用系统语义色(绿/橙/红),自动适配浅色与深色模式。
仓库内
docs/preview.html为可交互的完整静态预览(含全部页面与图例),可直接用浏览器打开查看。上方截图均由该文件渲染生成。
┌─────────────────────────┐ Wi-Fi (SoftAP) ┌──────────────────────────┐
│ 下位机 / 数据源 │ │ iOS 上位机 (本仓库) │
│ │ │ │
│ 光电前端 (660/940nm) │ │ NWConnection (TCP) │
│ │ │ TCP Socket │ 可在"无线连接"页配置 │
│ STM32F405VGT6 (12bit ADC)│ ───────────────────────▶ │ 默认 192.168.4.1:8080 │
│ │ │ 10 字节/帧, 4×16bit │ │ │
│ ESP8266 (汇承 HC, AP) │ │ receive(minimumIncomplete│
│ 默认网关 192.168.4.1 │ │ Length: maximumLength:) │
│ │ │ │ │
│ │ │ WaveformBuffer ×4 │
│ │ │ (@MainActor, Canvas绘制) │
└─────────────────────────┘ └──────────────────────────┘
SpO2-Wireless-iOS/
├── SpO2Wireless.xcodeproj/ # Xcode 工程文件
└── SpO2Wireless/
├── SpO2WirelessApp.swift # App 入口(@main)
├── Theme/
│ └── AppTheme.swift # 配色、卡片样式
├── Models/
│ ├── ConnectionSettings.swift # 连接配置:校验 + UserDefaults 持久化
│ ├── SensorFrame.swift # 10 字节定长帧解析 + 通道枚举
│ └── WaveformBuffer.swift # 单路波形滚动缓冲区(@MainActor)
├── Networking/
│ └── SensorConnection.swift # NWConnection TCP 客户端,定长帧读取
├── Views/
│ ├── RootView.swift # NavigationSplitView 根导航(iPhone/iPad自适应)
│ ├── SplashView.swift # 启动页
│ ├── ConnectionSettingsView.swift # 无线连接配置页
│ ├── MonitorView.swift # 实时监测页(状态 + 波形网格)
│ ├── WaveformCardView.swift # 单路波形卡片(标题 + 波形)
│ ├── WaveformCanvasView.swift # Canvas 波形绘制
│ └── AboutView.swift # 关于页
├── Assets.xcassets/ # 颜色资源(BrandPrimary / AccentColor / AppIcon)
└── Preview Content/ # SwiftUI 预览资源
| 项目 | 说明 |
|---|---|
| 语言 | Swift 5 |
| UI 框架 | SwiftUI(NavigationSplitView、Canvas、Form) |
| 网络 | Network framework(NWConnection,TCP) |
| 持久化 | UserDefaults |
| 部署目标 | iOS 16.0+ |
| 设备支持 | iPhone、iPad(TARGETED_DEVICE_FAMILY = 1,2),通用 App |
| 第三方依赖 | 无 |
- macOS + Xcode 15 或更高版本
- iOS 16.0+ 真机或模拟器(建议真机,便于连接 Wi-Fi 热点)
git clone https://github.com/Nathanielguo/SpO2-Wireless-iOS.git
cd SpO2-Wireless-iOS
open SpO2Wireless.xcodeproj在 Xcode 中选择目标设备(iPhone 或 iPad 真机/模拟器),⌘R 运行。
项目使用
GENERATE_INFOPLIST_FILE = YES(Xcode 自动生成 Info.plist),无需手动配置权限项;本地网络访问权限会在首次连接时由系统弹窗请求(iOS 14+ 的 Local Network 权限)。
- 给下位机上电,确认 ESP8266 进入 SoftAP(热点)模式。
- iPhone/iPad 连接 ESP8266 的 Wi-Fi 热点(网段
192.168.4.x,网关192.168.4.1)。 - 打开 App,进入"无线连接",确认/修改 IP 与端口(默认
192.168.4.1/8080)后点击"确认"。 - 进入"实时监测",点击"开始";首次连接会弹出 本地网络访问权限 请求,需允许。
- 状态指示变为"已连接"后,四路波形开始实时滚动。
排查建议
- 状态显示"连接失败":检查是否已连接到 ESP8266 热点、IP/端口是否正确、是否已授权本地网络权限(设置 → 隐私与安全性 → 本地网络)。
- 波形长时间无变化:检查下位机是否按 10 字节定长帧持续发送数据。
| 功能 / 模块 | Android (Java) | iOS (Swift) |
|---|---|---|
| 连接配置 + 校验 + 持久化 | FirstActivity + SharedPreferences |
ConnectionSettingsView + ConnectionSettings(UserDefaults) |
| TCP 定长帧接收 | SecondActivity + DataInputStream.readFully() |
SensorConnection + NWConnection.receive(minimumIncompleteLength:maximumLength:) |
| 波形数据模型 | 解包后的 4 个 int |
SensorFrame(10 字节 → 4×UInt16) |
| 波形绘制 | 自定义 View + Canvas(SpO2.java) |
WaveformCanvasView(SwiftUI Canvas) |
| 波形数据缓冲 / 线程安全 | synchronized + 主线程 postInvalidate |
WaveformBuffer(@MainActor + ObservableObject) |
| 连接状态指示 | 状态点 + TextView |
状态点 + Text,SensorConnectionState 枚举 |
| 主菜单导航 | MainActivity 三按钮 |
RootView(NavigationSplitView,iPad 侧边栏 / iPhone 导航栈) |
| 关于页 | ThirdActivity |
AboutView |
| 启动页 | SplashActivity(2 秒延时) |
SplashView(1.5 秒延时) |
- 算法落地:基于四路 DC/AC 计算 R 值与 SpO₂、心率(PR),并在 UI 上展示数值与异常报警。
- 历史数据:增加波形/数值的本地存储(如 SwiftData)与导出(CSV/PDF)。
- 断线重连:
SensorConnection增加自动重连与心跳保活。 - Apple Watch 配套:基于现有
WaveformBuffer/SensorConnection架构,扩展 watchOS 伴侣 App 实时显示关键数值。 - App Icon / 启动图:当前
AppIcon.appiconset为占位配置,建议补充实际图标资源。
- 当前仅实现波形显示,未包含 SpO₂ / 心率的数值计算与报警逻辑(与 Android 版一致)。
- 数据帧格式(10 字节定长)为硬编码,缺少协议版本协商机制。
AppIcon.appiconset未包含实际图标图片,需要在 Xcode 中补充。- 项目未配置签名团队(
CODE_SIGN_STYLE = Automatic),首次运行需在 Xcode 中选择开发者账号。
本项目为本科毕业设计配套教学/研究用途源码,仅供学习与算法验证参考。
⚠️ 本软件不是医疗器械,输出结果不得用于任何临床诊断或健康决策。如需用于医疗场景,必须满足相应法规与认证要求。
仓库未附带显式许可证;如需复用或二次发布,请先联系作者确认授权。



