Files
multi-simadmin/docs/ios-native.md
T
chick 95c653b3d3 docs(ios): 双通道(内网直通 + 公网中继)设计稿
- 拓扑:每节点一个 agent,只出站连中继,出口硬编码回环,把 SSRF 爆炸半径从整个内网收缩到单节点
- 信封:Ed25519 签名覆盖 nodeID/reqID/ek 防改投与错配,临时-静态 DH 加密,并写准前向安全的实际边界
- 授权:中继不得授权任何事,危险写确认改由手机产生、agent 校验,说明服务端签发令牌为何不可搬用
- iOS:引入 InstanceEndpoint 与 NodeTransport,origin 同时承担目标/去重键/Cookie 绑定三职的迁移路径
- 复用既有 ProblemDetails、FRESHNESS_STATUSES 与 server/proxy 策略,并要求策略抽为共享 JSON 防漂移
2026-09-15 14:55:45 +08:00

207 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# iOS 原生应用说明(当前实现)
本文是 iPhone 应用的唯一现行说明,内容与仓库代码一致。历史设计稿和执行计划保留在
`docs/superpowers/` 下,其中已被实现推翻的决策在本文第 9 节逐条列出。
- 当前版本:`0.2.2`,构建号 10
- 承载分支:`ios-native-ipa`
- 运行要求:iOS 16.0 及以上,`arm64`,Bundle ID `fun.chick.multi-simadmin`
- 产物:未签名 `MultiSimAdmin.ipa`,由 TrollStore 或用户自有签名流程安装
## 1. 形态
独立 iPhone 应用。应用直接以 HTTP/HTTPS 访问用户添加的每个 SimAdmin 节点,不经过
8788 控制台,不含 WebView,不内嵌 Node.js,也不与 Web 端共享数据库或进程。Web 前端和
Node 控制面仍然独立存在,两者只共享上游接口契约。
## 2. 导航
底部固定三个入口,高度 62pt(`AITabBar`):
| 入口 | 页面 | 内容 |
| --- | --- | --- |
| 节点 | `FleetView` | 节点总览、运行概览、标签筛选与批量归类、批量选择、添加与编辑实例 |
| 消息 | `MessagesView` | 跨实例短信读取、按实例与方向筛选、搜索、发送、删除 |
| 设置 | `SettingsView` | 主题外观、应用信息、本地数据(进入日志中心)、隐私与数据、数据清理 |
实例详情 `InstanceDetailView` 由节点卡片进入;日志中心 `LogsView` 只出现在
「设置 → 本地数据」里,不占用底部入口。启动参数 `--tab-messages`、`--tab-settings`
可直达对应 Tab,`--tab-detail`、`--tab-logs` 只在 Debug 构建生效,供逐页截图验证使用。
## 3. 页面能力
### 节点总览
- 运行概览:在线率与异常节点两枚大字结论、状态分布条与图例、八格两行的群集读数(信号、延迟、
存储、流量、CPU、内存、温度、电量),可折叠,折叠时保留前四格。检测进度与更新时间写在卡片
副标题里(`刚刚更新 · 已检测 6/6 台`),不占读数格;整群节点没有上报的读数保留占位,统一写成
一根短横 `—`,避免在四列窄格里被读成故障结论;栅格不会在七格与九格之间跳动。
- 标签归类:标签是唯一归类手段,分组概念已在 0.2.2 移除。标签条支持多选叠加,胶囊上直接显示
命中台数,可单个取消或全部清除;卡片内的标签同样可点,点一下即加入筛选。
- 批量标签:批量选择后一次给多台节点贴同一个标签,每个标签显示「未贴 / N/M / 全部」三态覆盖度,
点击即在整批上加减;可在同一张表里新建标签。
- 搜索:匹配名称、地址、运营商与标签。
- 节点卡片:顶部四条量表(信号、延迟、CPU、内存)配发丝进度,下面是号码、运营商、设备、存储、
温度、电量、运行时间等指标,超出一屏时折叠为「另有 N 项指标」。健康读数不着色,只有越过阈值
才出现告警或危险色。
- 批量选择:工具栏为 34pt 图标按钮(全选、删除、退出等高),勾选列独立于名称区域,
选中态不遮挡文字。
- 实例增删改:地址、名称、标签、访问凭据;删除前确认,并一并清除本地登录信息。
### 实例详情
- 头部卡片:地址与连接状态、四项仪表(信号、延迟、CPU、内存)、身份摘要(号码、运营商、网络、
IP)、模块可用度读数、标签。四项仪表排成两列发丝线栅格,读数在上、进度在下,缺数据时保留
空轨道,数据到位后卡片高度不变。
- 数据模块:设备、SIM、蜂窝网络、系统资源、CPU、连接状态共 6 个分区,逐模块独立加载,
单模块失败只标记该模块,不影响其余分区。
- 敏感值(IMEI、ICCID 等)默认隐藏,需要显式开启显示,离开页面后自动恢复隐藏。
- 本机保存的配置:地址、凭据状态、标签,以及登录、登出、重新检测。
### 消息中心
逐实例读取 `/api/sms/list` 后在本地合并,不做跨设备中转:
- 列表按时间排序,显示来源实例、方向、号码、正文与相对时间。
- 支持按实例筛选、按上行/下行筛选、按号码或内容搜索。
- 发送与刷新一起放在导航栏右侧,页脚不再另挂操作条;发送写入目标实例,失败可重试;
单条删除走该实例的上游接口,行内只留一枚红色线性图标。
### 日志中心与设置
- 日志中心:运行日志统一时间线、连接探测记录(结果、错误码、耗时)、设备诊断快照;
支持按级别、来源、实例、结果筛选与关键字搜索,支持清理过期连接日志。
- 设置:主题外观(跟随系统、浅色、深色,即时作用于全部页面)、应用信息与系统版本、
本地数据统计、隐私与数据说明、清除运行日志(不可恢复确认)。
## 4. 上游访问
只允许固定白名单,不存在任意 URL 代理:
| 方法 | 路径 | 用途 |
| --- | --- | --- |
| GET | `/api/health` | 可达性与版本 |
| GET | `/api/device` | 设备信息 |
| GET | `/api/sim` | SIM 与号码 |
| GET | `/api/network` | 蜂窝网络与信号 |
| GET | `/api/network/signal-strength` | 信号强度明细 |
| GET | `/api/stats` | 系统资源 |
| GET | `/api/stats/cpu` | CPU 明细 |
| GET | `/api/connectivity` | 连接状态 |
| GET | `/api/sms/list` | 短信列表(limit、offset、direction) |
| POST | `/api/sms/send` | 发送短信 |
| POST | `/api/sms/batch-delete` | 批量删除短信 |
| POST | `/api/auth/login` | 使用实例密码换取会话 |
| POST | `/api/auth/logout` | 注销会话 |
请求超时 30 秒,单响应体上限 262144 字节,错误统一映射为请求非法、需要登录、权限受限、不支持、
超时、传输失败、响应非法七类可读文案。会话 Cookie 按实例隔离保存在内存中,并绑定创建时
的节点地址,地址改变后旧 Cookie 立即失效。应用不请求定位、相机、麦克风、通讯录或后台
刷新权限,不声明任何后台模式。
## 5. 本地数据与安全
全部数据落在应用沙盒 `Documents` 目录,无 Keychain、无 SQLite、无服务端上传:
| 文件 | 内容 |
| --- | --- |
| `instances.json` | 实例名称、地址、标签、修订号 |
| `credentials.json` | 实例访问密码 |
| `log-center.json` | 运行日志、连接探测记录、诊断快照缓存 |
0.2.1 及更早版本写过的 `instance-groups.json` 与偏好键 `fleet.groupMode` 在升级后的首次启动
一次性删除。主题偏好存在 `UserDefaults`(键 `aiThemeMode`)。登录会话只存在于进程内存,应用退出即消失。
密码与 Cookie 不写日志、不进导出内容。删除应用即彻底清除本机数据。允许 HTTP 明文访问是
为了兼容局域网 SimAdmin,公网节点应由用户自行通过 HTTPS 反代暴露。
## 6. 设计语言
界面不含蓝色。品牌色是石墨与黄铜:浅色画布中性冷灰 `#F4F5F5`、纯白卡片、墨黑主操作
`#151819`;深色画布 `#080909`、低明度石墨分层 `#131515` / `#1B1D1E`、近白主操作 `#EEF1F1`。
颜色只保留给状态语义——危险 `#C12E28` / `#F77169`、告警 `#AA5C0F` / `#E9A63C`、成功
`#107A56` / `#42C784`,健康读数一律用墨色,避免整屏泛绿或整屏泛红。选中态用实心主色加
`onPrimary` 文字,不使用低透明度色雾,浅色深色两套主题下都必须一眼可读。
控件令牌集中在 `AITheme`:主按钮高 48pt(紧凑 44pt、大号 56pt)、工具栏按钮高 44pt(宽 104pt)、
导航栏图标按钮 34pt 方形(圆角 11pt)、输入框高 52pt、卡片圆角 22pt、按钮圆角 16pt、标签为
28pt 胶囊。同屏并排控件必须等高,选中态不得改变控件尺寸,卡片内部不再嵌套卡片——并列读数改用
发丝线分隔的栅格,正文与标题不使用负字距,字距为 0。
## 7. 构建与产物
```bash
./scripts/build-ios-ipa.sh
```
流程:`xcodebuild -scheme MultiSimAdmin -configuration Release`(`generic/platform=iOS`)编译
可执行文件 → 手工组装 `Payload/MultiSimAdmin.app` → 用 `xcrun actool` 编译 `Assets.xcassets`
得到 `Assets.car` 并合并图标元数据到 `Info.plist` → `zip` 打包 → 生成 `.sha256`。产物:
- `build/ipa/MultiSimAdmin.ipa`
- `build/ipa/MultiSimAdmin.ipa.sha256`
脚本不需要证书与描述文件,不做任何签名改动;`Assets.car` 缺失时直接失败退出,避免发布没有
图标的包。
应用图标由脚本光栅化生成,不使用手工位图:
```bash
cd apps/ios && swift Design/generate_app_icon.swift \
Sources/MultiSimAdmin/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon1024.png
```
图标为扁平构图,不用立体卡与投影:石墨底、黄铜 SIM 面板(切角在左上)、三根底部对齐的递增
信号条,29pt 尺寸下轮廓仍然可读。`apps/ios/Design/AppIcon.svg` 是同构图参考稿,实际构建使用
由 `Design/generate_app_icon.swift` 光栅化出的 PNG,面板边长、圆角、切角与信号条间距都可用
环境变量调整。
## 8. 验证方式
```bash
cd apps/ios
swift build
swift test # 48 个用例
xcodebuild -scheme MultiSimAdmin \
-destination 'platform=iOS Simulator,id=<UDID>' \
-configuration Debug build
```
单元测试覆盖实例仓储与修订冲突、地址规范化与去重、标签归一化、上游路由白名单、会话隔离、
连接探测分类、短信解析与分页、设备快照解析、日志仓储与清理、主题模式持久化、时间相对显示、
版本号契约。界面改动在 iPhone 17 Pro 模拟器上以截图逐页核对浅色与深色两套主题,重点检查控件
等高、文字不溢出、按钮在深色下不消失。
## 9. 与设计稿的偏离
`docs/superpowers/specs/2026-09-08-ios-native-ipa-design.md` 的以下决策已被实现推翻,该文档
只作为历史背景保留:
| 原设计 | 当前实现 | 原因 |
| --- | --- | --- |
| 底部五 Tab:节点/消息/通知/日志/设置 | 三 Tab:节点/消息/设置 | 应用内通知中心依赖进程常驻,关闭后不可用;日志属于低频排查,收进设置 |
| 通知通道、规则、投递队列、立即投递 | 未实现 | 同上,移除后不再保留只读残壳 |
| 实例密码存 iOS Keychain | 沙盒内 `credentials.json` | Keychain 在 TrollStore 环境下读写不稳定 |
| GRDB + SQLite 控制面库 | 沙盒内 JSON 文件 | 去掉第三方依赖,数据结构与备份语义更直观 |
| 操作目录、任务、审计、维护、备份 | 未实现 | 高风险写操作与常驻调度不在 iPhone 前台场景内 |
| 设备模块 13 项(含通话、eSIM、OTA、WiFi Calling、自动化) | 6 个只读模块 + 短信读写 | 上游只保留有稳定读取价值的接口,其余按需在后续版本评估 |
| 浅灰画布、青绿主按钮 | 深浅双主题、石墨墨色主操作、黄铜点缀 | 0.2.x 视觉重构结论,用户明确排除蓝色 |
| 实例分组(分组视图、分组编辑器、分组仓储) | 标签归类 + 批量标签 | 分组与标签职责重复,分组作为实体在 0.2.2 移除 |
## 10. 已确认的移除边界
不实现:应用启动后的周期轮询、后台任务与静默推送、Cron 与自动投递、自动备份与自动日志修剪、
控制台自更新、多用户与远程访问、全局访问密码。
保留:进入前台与下拉刷新触发的一次同步、页面可见时的按需刷新、用户主动发起的登录、检测、
发送、删除与日志清理。
## 11. 文档索引
- [docs/ios-native.md](ios-native.md):本文,现行说明
- [docs/ios-relay-architecture.md](ios-relay-architecture.md):双通道(内网直通 + 公网中继)设计稿,未实施
- [docs/ios-native-0.2.2.md](ios-native-0.2.2.md):0.2.2 构建 10 发布说明与校验值
- [docs/ios-native-0.2.1.md](ios-native-0.2.1.md):0.2.1 构建 6 发布说明与校验值
- [docs/ios-native-0.2.0.md](ios-native-0.2.0.md):0.2.0 发布说明
- [docs/superpowers/specs/2026-09-08-ios-native-ipa-design.md](superpowers/specs/2026-09-08-ios-native-ipa-design.md):历史设计稿
- [docs/superpowers/plans/2026-09-08-ios-native-ipa-foundation.md](superpowers/plans/2026-09-08-ios-native-ipa-foundation.md):地基执行计划(已完成)