CLAUDE.md:新增「参考原项目 daoqi」规则 + LaunchScreen 典型案例

新增「原项目 daoqi:遇到问题时的参考来源」段:
- 明确原 daoqi 项目路径 ../daoqi/(与 ylgamehall 同级目录)
- 列出何时主动去读原项目(iOS 行为不符预期 / Info.plist 不确定 / 桥接
  字段 / SDK 时序 / 渠道注入 / 老 hack 等)
- 怎么用原项目(先查关键文件 → grep 同名 key → 看 git log → 对照差异)
- 与「原则 B:内部自由重构」不冲突:参考是"必须做的清单"和"已踩过的坑"
  备忘,不是"实现细节照抄"

新增 LaunchScreen orientation 典型案例:
- 症状:启动图横躺被旋转 90°
- 错误做法:凭文档推测、纯调 storyboard / contentMode / 反复换素材
- 去原项目找到 msext 用 LaunchImage Asset Catalog(iOS 8 时代)的"按
  orientation 自动旋转 portrait 资源"魔法 — 这套机制 iOS 14+ 已 deprecated
- 新项目用 LaunchScreen.storyboard 没有自动旋转,必须三步组合:
  1. 素材物理像素就是横屏(sips -r -90 一次性旋转 msext 残留 portrait 素材)
  2. Info.plist 显式补无后缀 UISupportedInterfaceOrientations
  3. UIImageView scaleAspectFit + 黑底
- iOS launch snapshot 缓存粘滞:开发期改启动相关任意一项后必须卸载重装
  才能看到新效果;终端用户不受影响

文档索引表加入 ../daoqi/ 一行,加突出可见性。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
joywayer
2026-06-22 03:59:29 +08:00
co-authored by Claude Opus 4.7
parent a6433d9e95
commit a20498f898
+56
View File
@@ -23,6 +23,61 @@ daoqi 仓库当前并存两条工作线:
--- ---
## 原项目 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 自由设计;只是设计前先确认"我没有漏掉原项目实际需要解决的事"
### 典型案例:LaunchScreen orientation(启动图方向错误)
- **症状**:新项目启动图渲染成竖向矩形再被整体旋转 90°,画面横躺在中间
- **错误做法**:凭 Xcode 26 文档推测、纯调整 storyboard / contentMode / 反复换素材
- **去原项目找答案**`daoqi/msext/Info.plist` + `msext.xcodeproj/project.pbxproj`
- 发现 1Info.plist 用的是**顶层无后缀的 `UISupportedInterfaceOrientations`**(值 = landscape),**没有** `~iphone` / `~ipad` 后缀变体
- 发现 2:根本**没有** `UILaunchStoryboardName`,用的是 `ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "LaunchImage-1"`iOS 8 时代的 LaunchImage Asset Catalog 机制)
- **原项目为什么稳**
- 它的所有 LaunchImage PNG`Default-568h@2x` / `LaunchImage-1-800-667h@2x` 等)**物理像素都是竖向、画面内容横躺**
- iOS 8 LaunchImage Asset Catalog 内置"按 device idiom + orientation 自动选图 + 系统级 90° 旋转"魔法,会读 Info.plist 顶层 `UISupportedInterfaceOrientations` 决定是否旋转 portrait 资源
- 因此一张物理 portrait 的 PNG 在横屏设备上能被正确旋转后铺满
- **不能照搬到新项目**
- LaunchImage Asset Catalog 在 iOS 14+ 已 deprecated,新项目按苹果推荐用 `LaunchScreen.storyboard`
- LaunchScreen.storyboard **没有自动旋转 portrait 资源**的魔法,UIImageView 直接渲染 PNG 物理像素
-`docs/res/Res/Default-568h@2x` 这类**物理 portrait + 画面横躺**的 msext 残留素材直接塞进 LaunchScreen.storyboard 就会看到躺倒画面
- **新项目(LaunchScreen.storyboard)的正确组合**
1. **素材必须物理像素就是横屏的**(必要时用 `sips -r -90 -s format png` 一次性把 msext 残留 portrait 素材逆时针 90° 输出为标准 PNG,物理像素正确)
2. **Info.plist 显式补一份无后缀 `UISupportedInterfaceOrientations = landscape`**Xcode 26 General → Deployment Info UI 只写带后缀的 `~iphone` / `~ipad`,少了无后缀 key 会让 LaunchScreen 阶段——device idiom 尚未识别的早期窗口——fallback 到 portrait 渲染再被旋转)
3. UIImageView `contentMode = scaleAspectFit` + 黑底(比 16:9 更宽的现代横屏设备左右补黑边,保画面完整不裁切 logo)
- **iOS launch snapshot 缓存粘滞(开发期 iteration 坑)**
- iOS 为加速启动,会把首次渲染的 LaunchScreen 缓存为 PNG snapshot 存到 app sandbox`Library/Caches/Snapshots/<bundleID>/com.apple.UIKit.SplashBoard/`),后续启动不重渲染
- **Xcode 覆盖安装 .app 不会清 sandbox 缓存**,所以改了 Info.plist / LaunchScreen.storyboard / 启动图素材后,Run 出来仍可能是旧 snapshot
- 改完启动相关任意一项**必须做**:长按 app → 删除 → Xcode 重新 Run;或模拟器 Erase All Content and Settings;或 `xcrun simctl uninstall booted <bundleID>`
- **终端用户不受影响**:从 IPA 首次安装、或升级新 IPA 第一次启动后即被 iOS 自动刷新;只是开发期反复迭代同一台 device 时会被迷惑
---
## 文档索引 ## 文档索引
| 文档 | 角色 | 何时读 | | 文档 | 角色 | 何时读 |
@@ -31,6 +86,7 @@ daoqi 仓库当前并存两条工作线:
| `docs/H5-Native-Contract.md` | H5 ↔ 原生 桥接**契约**(黑盒可观察行为) | 涉及桥接接口必读 | | `docs/H5-Native-Contract.md` | H5 ↔ 原生 桥接**契约**(黑盒可观察行为) | 涉及桥接接口必读 |
| `docs/H5-Native-Implementation-Design.md` | 新外壳实施蓝图(架构、模块、代码骨架) | 实现新外壳必读 | | `docs/H5-Native-Implementation-Design.md` | 新外壳实施蓝图(架构、模块、代码骨架) | 实现新外壳必读 |
| `docs/Development-Plan.md` | 开发执行计划(Phase 0–10、依赖图、进度追踪) | 排期 / 进度更新必读 | | `docs/Development-Plan.md` | 开发执行计划(Phase 0–10、依赖图、进度追踪) | 排期 / 进度更新必读 |
| `../daoqi/`(仓库同级目录) | 原项目 msext 工作参照实现 | 遇到 iOS 行为差异 / 渠道注入 / 桥接 / SDK 初始化等不确定问题时,**优先参考此处**而非凭推测,详见下文「原项目 daoqi:遇到问题时的参考来源」 |
--- ---