# daoqi 项目协作约定(面向 Claude / AI 助手) > 本文件随 daoqi 仓库分发,任意设备 clone 后均按此约定执行。 --- ## 适用范围声明 **本 CLAUDE.md 仅适用于 daoqi 项目自身**。 - 父目录(任何上级目录)下可能存在其它 CLAUDE.md 文件,那些文件**不是为本项目编写**的,与 daoqi 项目无关,**不参照、不继承、不引用**。 - Claude / AI 助手在本项目工作时,只读取并遵循本文件(`./CLAUDE.md`)与本项目 `docs/` 下的文档,不向上递归引用父级 CLAUDE.md。 - 如果在对话上下文中出现父级 CLAUDE.md 的内容(由工具自动加载),应当忽略,以本文件为唯一权威。 --- ## 项目内容 daoqi 仓库当前并存两条工作线: 1. **现有 iOS 外壳(`msext` target)** — 已上线版本。Objective-C(MRC,未启用 ARC),最低 iOS 9.0;原生外壳 + 内置 H5(`gamehall.zip` 解压到沙盒)+ WebViewJavascriptBridge 桥接。 2. **新外壳设计(greenfield 重写)** — 计划中的下一代版本。设计原则、接口契约、实施蓝图见 `docs/` 下两份文档。 --- ## 原项目 daoqi:遇到问题时的参考来源 **原 daoqi 项目代码位于** `/Users/joywayer/Documents/Works/YouleApps/iOS/youle_app_ios/daoqi/`(与 ylgamehall 同级目录)。该项目已稳定运行多年(msext target),是同一 H5 业务、同一渠道分发模式、同一启动流程的"工作参照实现"。 ### 何时主动去读原项目 新项目实施过程中**遇到任何一类下述问题,第一动作是去 daoqi 找参照**,而不是凭推测搭方案: - **iOS 行为不符合预期 / 与文档描述有差异**(如本次的 LaunchScreen orientation 问题:iOS 26 + Xcode 26 默认 Build Settings 写法导致启动图被 portrait 渲染再旋转 90°) - **某个 Info.plist key / Build Settings 不确定该不该加 / 加哪种变体** - **某个 H5 桥接 handler 的返回值结构 / 字段命名 / 类型不确定** - **某个三方 SDK 的初始化时序 / 回调链疑似有顺序依赖** - **渠道注入 / 启动流水线 / 升级逻辑某一步与设计文档对不齐** - **某个看似可改的"老 hack"想清掉,但不确定该 hack 是否解决过某个具体问题** ### 怎么用原项目 1. **先查关键文件**:`daoqi/msext/Info.plist`、`daoqi/msext/Class/AppDelegate.{h,m}`、`daoqi/msext/Class/UI/NewRootVC.m`(启动流水线全部在此)、`daoqi/Podfile`(看用了什么三方) 2. **grep 同名 key / 同名 handler**:例如 `grep -r "UISupportedInterfaceOrientations" daoqi/msext/Info.plist` 3. **看 git log / git blame**:原项目积累的"看似古怪的写法"通常都有当年的修复故事 4. **对照差异**:原项目稳定运行的写法是事实基准;新项目偏离它的部分必须有明确的"为什么改"的理由(通常出现在 `docs/H5-Native-Implementation-Design.md` 的 ADR 或 §6.3.6 等差异表里) ### 与「原则 B:内部自由重构」不冲突 - 参考原项目 ≠ 照抄原项目的实现细节 - 参考原项目 = 把它当作 **"哪些事必须做"的清单** 和 **"哪些坑已经踩过"的备忘** - 新项目的现代化重构(Swift 6 / SwiftUI / actor 隔离 / SPM 依赖等)依然按原则 B 自由设计;只是设计前先确认"我没有漏掉原项目实际需要解决的事" ### 案例存档(按需读取) 以下两个完整案例已移到 `.claude/skills/daoqi-lessons/SKILL.md`(用到时再加载,不常驻上下文): - **典型案例:LaunchScreen orientation(启动图方向错误)** — 处理启动图 / 启动方向问题时读 - **典型案例:H5 与原生通讯接口的真实路径** — 处理 H5 读渠道值 / `app_*.js` 变量 / `window.settings` polyfill 时读 下面保留的 `app_*` 注入时序案例是原则 A 的规范性说明,常驻不移出。 ### 典型案例:`app_*` 注入时序问题(原则 A 不可妥协) - **症状**:H5 端读到 `app_gameconfig` 等关键变量是 H5 zip 包内默认占位值,不是 ChannelConfig.plist 的实际渠道值 - **调研发现**(按 CLAUDE.md「先看原项目」规则):原 msext 在 `NewRootVC.viewDidLoad → initJSdata`(`loadFileURL` **之前**)用 `writeToFile:` 把 `app_data.js` 写入沙盒,H5 启动时通过 `