iOS 客户端
星线 iOS 是使用 SwiftUI 编写的原生 iPhone 客户端。本文说明工程入口、状态管理、本机数据与系统能力接入,面向需要运行、维护或扩展客户端的开发者。
工程与系统要求
ios-app/project.yml 是 XcodeGen 工程配置来源,生成的工程名和主 scheme 都是 StarlineWorkbench。配置声明 Swift 6.0、最低 iOS 17.0、设备族为 iPhone,Bundle ID 为 cn.thestarline.workbench。当前没有 iPad 专用或 watchOS target;独立手表版仍属待办。
项目直接导入 FoundationModels,开发环境需要包含该框架的 SDK;仓库 README 的开发流程使用 Xcode 27 和 XcodeGen。最低运行系统与编译 SDK 是不同要求:iOS 17 可以运行基础功能,系统模型识别仅在 iOS 26 及以上且模型可用时启用。
主要外部依赖为 LiveKit Swift SDK(from: 2.17.0)和本仓库 chat-crypto/dist/StarlineChatCrypto.xcframework。Swift Package 版本声明允许兼容版本解析,不能将下限当作每次构建的实际锁定版本。加密核心需按仓库构建流程准备,详见消息与媒体。
启动与状态架构
StarlineWorkbenchApp 在启动时创建 ChatStore,并将其交给 CallSystemBridge。根视图分别持有 LocalWorkspaceStore、MemoryStore、MomentsStore 和附近地点状态,通过 SwiftUI Observation、@State 与环境传递给功能视图。
默认底部为“聊天、工作台、我的”;记忆可以通过设置加入底部导航。默认页面和扫码按钮开关使用 @AppStorage 保存。工作台路由使用 NavigationStack,任务编辑、扫码和账号确认使用独立展示状态。界面 locale 当前固定为简体中文。
启动异步恢复待处理登录与聊天会话,回到前台重新检查会话。onOpenURL 先尝试身份回调,再处理好友链接,避免把登录回调当作普通扫码内容。身份流程与回调限制见认证。
数据与网络流
任务、网站收藏和最近访问由 LocalWorkspaceStore 写入 App 私有的 workspace.json。记忆由单独的 MemoryStore 管理,其索引、附件和密钥策略见本地记忆。这两类本机数据不因聊天登录而自动同步。
聊天通过 ChatAPI、URLSession 和模型解码访问聊天服务;默认地址为 https://chat.thestarline.cn。Debug 可用 STARLINE_CHAT_BASE_URL 指定测试地址,代码只接受 HTTPS 或 HTTP 回环主机,并拒绝包含用户信息、查询或片段的覆盖值;Release 不读取该环境覆盖。不要把测试地址或真实凭据写进源码。
新事状态由 MomentsStore 复用聊天身份管理;音视频使用 LiveKit,系统来电使用 CallKit/PushKit。扫码使用 VisionKit 的二维码识别,相册图片识别和手动输入保留为替代入口。普通网页与账号确认网页分别管理浏览会话。
运行与扩展
在仓库的 ios-app 目录执行:
xcodegen generate
open StarlineWorkbench.xcodeproj
选择 StarlineWorkbench scheme 运行;新增源文件或修改系统能力后同步 project.yml 与工程。新增领域数据应先明确属于本机工作台、加密记忆还是服务端聊天,随后在对应 Store 增加操作,再由视图呈现错误和加载状态,避免直接在视图中混合网络和持久化。
真机签名须使用维护者自己的开发团队与描述文件。工程声明相机、麦克风、使用期间定位,以及 location/audio/voip 后台模式;APNs 环境按 Debug/Release 区分。配置存在不能证明推送、后台定位或通话已完成真机验收,详见权限与可访问性。
模块边界与排错入口
| 现象或需求 | 优先检查 | 不能据此推断 |
|---|---|---|
| 本机任务或网站读取失败 | LocalWorkspaceStore 的快照解码与原子写入 |
聊天账号重新登录会恢复工作台 |
| 记忆库无法读取 | MemoryStore.loadError、Keychain 可用性和文件认证 |
空列表就是原来没有记忆,或改账号密码能恢复密钥 |
| 浏览器成功但账号为空 | ChatNativeAuth 的 pending、回调和 exchange |
打开 Account 页面已经取得聊天 token |
| 消息一直 sending/failed | ChatStore pending 与 clientId 合并 |
普通队列具备持久离线发件箱 |
| 通话 active 但无画面 | ChatCallCoordinator 的 Room、权限与远端轨道 |
信令 active 等于媒体接通 |
| 后台位置未更新 | ChatLiveLocationManager、权限、共享范围与更新时间 |
城市贴纸识别会自动开启持续共享 |
会话和 pending 使用聊天 Keychain service,属性为首次解锁后仅本设备可用;记忆密钥使用另一 service,要求当前设备解锁。LocalWorkspaceStore 的普通快照不因此共享记忆加密。普通聊天队列属于当前 Store 内存;独立 MLS 传输器才有自己的加密 checkpoint,当前主界面不能继承它的全部恢复能力。
新增功能时需区分主线程状态与异步响应。当前多个关键路径会在 await 后检查 token、用户、聊天目标或 operation,防止迟到结果污染新状态;这不表示所有新增请求可以省掉检查。把页面隐藏、后台暂停、网络重试、进程重建和明确退出各自测试,生命周期细节见客户端生命周期。
个人任务的截止筛选和网站去重见工作台,Date 编码和 vault 格式见本机数据格式,记忆打包与 Account 对接缺口见记忆转出。客户端当前只保存转出契约;权威 Account 版本缺少对应 redeem 路由,不能由分享代码存在推断多因素转出已可用。
验证边界
仓库包含领域、存储、加密、聊天、城市贴纸及 UI 测试。本篇依据当前源码编写,本轮未重新构建或启动模拟器,也未核验商店发行版本。历史测试与本次执行结果应分别记录;公网登录、两台真机跨网络通话、后台来电及实际权限恢复仍须走真实路径,参考测试与发布。