Files
Commilitia-Drop/ios/CDrop/REALDEVICE.md
T
admin 127070e226 设备名与令牌解耦 + iOS Broker 应用内登录 / 消息 / 图库 / 记录持久化 + 三端 bug 修复
设备名与令牌解耦(presence 按 device_id 键控):
- hub 主键改稳定 device_id(presence / online / kick 用之),peer 路由仍按设备名经 hub 内 clientFor 解析——不动传输核心;Client 加 Name + 连接键,PresenceDevice 加 device_id,sse 传 claims.DeviceID,publishPresence 按 device_id 判在线、name 取自 devices 表
- 改名走已有 PATCH /api/devices/{device_id}(不重铸会话、不换 token、不中断 SSE)+ hub.Rename 更新活跃连接名 + 重广播 presence,全端即时无重复项;sessions 列表 name 用 devices 表覆盖 broker Label;web 改名从重铸迁到 PATCH,iOS 设置页即时改名;DeviceItem / DeviceInfo 按 device_id 键控判本机
- 移除「需移除两次」:publishPresence 不再把「有 device_id 但无 devices 行」的 live 连接当在线(吊销后用未过期 token 重连的僵尸),只显示 code-less 连接;合法重登新建行故正常
- revoke 对无 broker 会话的本地行也清(清掉合成测试 / 幽灵设备);跨端吊销 / 断连一律按 device_id Kick

iOS Broker 应用内登录(免扫码):
- BrokerLogin.swift:ASWebAuthenticationSession 跑 broker /device/authorize + /device/token 的 PKCE 设备授权流(对齐桌面 loopback,自定义 scheme cdrop://auth-callback 回调)→ /api/auth/device-session 代铸出带真名 + 稳定 device_id 的设备会话;DeviceIDStore 跨登录复用 device_id 杜绝重登重复
- LoginView 主登录改 broker 账号登录、扫码降级为可展开备选

iOS 功能补全:
- 设备间消息(引擎 main.ts 单条增量过桥 + onNativeEvent sendMessage;EngineController 消息状态 + 新 MessagesView 会话 UI;后端 /api/message 已就绪)
- 图库发送(PhotosPicker 文件 / 图库菜单 → stagePhotoData → 复用 cdrop-file 发送链路;NSPhotoLibraryUsageDescription)
- 传输历史 / 消息记录持久化(RecordsStore 落 Application Support JSON,跨重启存活)+ 长按删除 + 清空(二次确认)
- 进行中传输主动取消 / 立即切中继(详情页两按钮,复用引擎桥命令)
- 身份愈合(引擎 /api/me 取真实显示名经 identityUpdated 回报 Keychain,修扫码登录「用户显示 UUID」)
- 触发本地网络权限(NWBrowser 浏览 _cdrop._tcp)使 WKWebView WebRTC 取 host 候选

iOS 发送 / 启动修复:
- 发送在读文件即失败:引擎在 https 源下 fetch("cdrop-file://") 跨源 + Range 头触发 CORS 预检被拦 → 改走原生桥 bridgeFileSource / readFileSlice(512 KiB 分块 base64),绕开 CORS、整文件仍不整体进内存
- 冷启重开「missing injected session」:EngineWebView.makeUIView 在 boot 注入前确定性接好 auth,消除注入竞态

桌面 bug 修复:
- 登出静默失败:window.confirm 在 Wails WebView 失效(返回 falsy 致动作被静默跳过)→ 跨平台 DOM 确认弹窗(utils/confirm 的 Promise 式 confirmDialog + ui/ConfirmHost 的 Mantine Modal)取代之;登出改 await 先吊销 broker 会话再清本地(桌面 clearDesktopSession 会丢 Go 侧 refresh 的竞态)
- 扫 iOS 登录二维码被拒「不是本站的码」:wails:// 源永不等 https 站点源 → 桌面放宽 parseLinkApprovalUrl 的 origin 等值校验(仍留 /link 路径 + r/c;批准 r/c 一律发往本端后端、外站码只 404,无开放重定向)
- macOS 本地网络权限触发(localnetwork_darwin NWBrowser + Info.plist 键);相机修复(NSCameraUsageDescription)

web / 跨端:
- presence 透传 device_id + 离线检测按 device_id;会话列表随 presence 防抖重拉(已登出设备自动从列表消失,不再需手动刷新);移除设备 / 清剪贴板 / 撤销令牌 / 登出均改 DOM 确认弹窗

分发 / 签名:
- 真机签名从手动 scaffold 改自动 provisioning(删 Signing.xcconfig,project.yml 去 profile specifier,just ios-device 用 -allowProvisioningUpdates + ASC 团队 key);App Group 改名 group.net.commilitia.Commilitia-Drop(含 entitlements)
- hub 测试加 device_id 键控 + 改名解耦回归(-race)
2026-06-27 03:50:04 +08:00

82 lines
5.3 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.
# cdrop iOS 真机分发手册
把 cdrop 装到你自己的 iPhone(开发签名)。代码侧全部就绪并经模拟器验证;真机只差**账号 + 签名**这一层。本手册走 **ASC API Key 自动 provisioning + 全 CLI** 路线——一把 App Store Connect API Key`-allowProvisioningUpdates` 自动登记连接的设备 + 创建/更新 App ID / App Group / Push / profile / 开发证书,构建装机一条命令,**全程不碰 Xcode GUI、不必手动建 profile**(绕过手动 profile「设备列表只剩 Mac」的坑)。
## 包名与标识
| 项 | 值 |
|---|---|
| 主 app Bundle ID | `net.commilitia.Commilitia-Drop` |
| Share Extension | `net.commilitia.Commilitia-Drop.share` |
| 控件扩展 | `net.commilitia.Commilitia-Drop.widgets` |
| App Group | `group.net.commilitia.Commilitia-Drop` |
| APNs topic(服务端 `CDROP_APNS_TOPIC` | `net.commilitia.Commilitia-Drop` |
## 前置
- 付费 Apple Developer Program$99/年)。
- 一台 iPhoneiOS 26+ MacXcode 26 命令行工具)。
- 一个已登录的 cdrop(网页 / 桌面)——用来扫码批准本机登录。
---
## A. ASC API Key + .env(核心,一次性)
`-allowProvisioningUpdates` 凭一把 App Store Connect API Key 替你在门户自动登记设备、建/改 App ID(含 App Groups + Push 能力)、建 App Group、建 profile、建/下开发证书——**不必手动建 profile**。
**生成 API Key**appstoreconnect.apple.com → **用户和访问****集成****App Store Connect API****团队密钥** → 「+」→ 角色 **Admin**(要能管设备 / profile / 标识符)→ 命名 → 生成 → 下载 `AuthKey_XXXXX.p8`**仅一次**)。记下三样:
- **Key ID**(密钥行里那串,10 位)
- **Issuer ID**(密钥页顶部,UUID 形)
- **Team ID**(账号 **Membership** 里,10 位)
**配 `.env`**(仓库根目录,已 gitignore,公开仓库不留账号凭据):
```
CDROP_TEAM_ID=ABCDE12345
CDROP_ASC_KEY_PATH=/绝对路径/AuthKey_XXXXX.p8
CDROP_ASC_KEY_ID=XXXXXXXXXX
CDROP_ASC_ISSUER_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```
`.p8` 放仓库外即可,`CDROP_ASC_KEY_PATH` 指它绝对路径(落本目录则被 `*.p8` 忽略)。
> 你若已在门户手动建过 App ID / App Group / 证书,自动 provisioning 会复用、不冲突。**「手动建 profile 时设备列表只剩 Mac」**=那台 iPhone 在 **Devices** 里被登记成了 macOS 平台(登记表单 Platform 默认 macOS);自动 provisioning 直接按连接的真机重登记,绕过此坑。
**顺手:APNs Auth Key**(发推送用,与上面 ASC Key 是两码事):门户 **Keys** → 勾 **Apple Push Notifications service** → 下载 `AuthKey_YYYYY.p8`(仅一次),记 Key ID + Issuer ID(服务端配,见 C)。
---
## B. 构建装机(全 CLI
```sh
just ios-devices # 手机插 USB,读 UDID
just ios-device <你的设备UDID> # 自动 provisioning 构建 + devicectl 装机
```
- `just ios-device` `xcodegen generate``xcodebuild -allowProvisioningUpdates`(凭 .env 的 ASC Key 自动签名 + 登记设备 + 建 profile)→ `xcrun devicectl device install app`。无 Xcode GUI。
- 首次装机后,iPhone 上首启该开发者 app 即可直接跑(付费 ADP 开发证书,无需手动「信任开发者」)。
---
## C. 服务端前置
1. **引擎可达**:真机上引擎 WebView 加载 `https://drop.commilitia.net/engine.html`——该文件随 cdrop 二进制部署到 prod(`//go:embed` 进 binary`just docker-image` 含最新 `dist`)。手机要用,prod 须是含本轮改动的最新部署。
2. **APNs 真发**:把 A 里那把 **APNs Auth Key** `.p8` 放到服务器,给后端容器配 `CDROP_APNS_KEY_PATH` / `CDROP_APNS_KEY_ID` / `CDROP_APNS_TEAM_ID` / `CDROP_APNS_TOPIC=net.commilitia.Commilitia-Drop` / `CDROP_APNS_ENV`Xcode 开发构建的 device token 属 **sandbox**,故联调填 `sandbox`)。缺配置则推送惰性关闭,其余功能照常。
3. 本机联调可选:环境变量 `CDROP_ENGINE_URL` 指向可达引擎。
---
## D. 只能真机验的清单
代码已实现,下列是真机才能验的点:
- [ ] 液态玻璃真机渲染(陀螺仪高光 / 动效)。
- [ ] 扫码登录:本机显码 → 已登录 cdrop 扫码批准 → 进主界面(强制 full/persist)。
- [ ] **本地网络权限 + 同内网直连**R-iOS-6):首次同内网传输弹 `NSLocalNetworkUsageDescription`;授予后 ICE 收 host 候选、走真直连;拒绝则回退中继仍可传。
- [ ] 发送 / 接收:选文件 → 选设备 → 对端收到;对端发来落 Files(Documents)。
- [ ] **大文件流式发送**(R-iOS-4 已实现):发大文件,WebView 内存应有界(按 Range 块拉取,不整文件入内存)。
- [ ] **后台续传**R-iOS-1 / R-iOS-3):传输中切后台 → `BGContinuedProcessingTask` 系统进度 UI;验 WKWebView JS 是否随之保活(不保活则退化为回前台续传,可接受)。
- [ ] **APNs 推送**:离线设备收「收到文件」通知(需 C2 的 `.p8`)。
- [ ] **Share Extension**:别的 app 分享 → 选 Commilitia Drop → 唤起主 app 选设备发送。
- [ ] **控制中心剪贴板两控件**:控制中心加「上传 / 拉取剪贴板」控件 → 锁屏 / 解锁态点按 → 云剪贴板读写。