日期:2026-05-20
状态:已评估,当前发布版暂缓执行
相关模块:SmartStartService、Smart Start catalog 生成脚本、build.sh、CatalogOps 多语言备注 QA
当前 Smart Start 运行时目录使用单个资源文件:
SmartStartUltimateDefaultCatalog.json
该 JSON 同时承载两类信息:
rank、name、normalizedName、bundleIdentifier、defaultTag、sourceEvidencenotes产品侧提出一个合理问题:用户通常只使用一种界面语言,很少频繁切换语言。如果所有语言 notes 都汇总在同一个 JSON 中,App 会解析大量当前用户用不到的备注内容。后续如果支持按需下载语言包,所有语言混在单文件里也不利于拆包。
将 Smart Start 资源拆成两层:
SmartStartUltimateDefaultCatalog.json
SmartStartUltimateDefaultCatalog.notes.zh-Hans.json
SmartStartUltimateDefaultCatalog.notes.en.json
SmartStartUltimateDefaultCatalog.notes.ja.json
...
其中:
en -> zh-Hans。该方案的长期优点:
架构师结论:**不建议在临近市场发布前执行这次拆分**,除非它是为解决明确的包体或启动性能阻塞。
主要理由:
SmartStart_UltimateDefaultCatalog.json 约 1.7 MB,体积并不大。zh-Hans,尚未真正塞入 29 种语言 notes。结论不是否定方向,而是建议把它作为下一版资源格式升级处理,不进入当前市场发布版。
当前 SmartStartService.relocalizeDefaultNotesForCurrentLanguage 通过 matched.notes.values 判断用户当前备注是否属于系统默认备注。只有确认当前备注仍是系统默认备注时,才会切换成新语言备注。
如果运行时只加载当前语言 notes,系统可能不知道用户当前保存的旧语言默认备注,导致两个问题:
这是最高风险点,因为它触及用户数据安全。
相关代码:
Apptag/SmartCategorization/SmartStartService.swift
- relocalizeDefaultNotesForCurrentLanguage
- makeDraft
- applyDraft
当前 makeDraft 会把 matched.notes?.values 作为 defaultNoteCandidates,用于后续判断是否可以安全替换已有备注。
如果拆分后只加载当前语言 notes,候选集会变窄。首次语言切换、重新应用系统初始方案、恢复默认方案时,系统对“哪些备注是系统生成的默认备注”的判断会变弱。
当前 build.sh 只复制:
SmartStartUltimateDefaultCatalog.json
SmartStartUltimateDefaultCatalog.csv
SmartStartAppDefaultTags.csv
拆分后必须复制全部 SmartStartUltimateDefaultCatalog.notes.<lang>.json 文件,并且应对关键 fallback 文件做构建门禁:
notes.zh-Hans.json 必须存在。notes.en.json 必须存在。拆分 notes 后,notes 文件必须通过稳定 key 与基础 catalog entry 关联。
候选方案:
normalizedNamebundleIdentifierrankentryID架构师认为不能只草率使用 normalizedName 或 rank:
normalizedName 可能碰撞。rank 会随排序变化而不稳定。bundleIdentifier 对无 bundle ID 的 App 不够完整。更稳妥的做法是新增稳定 entryID,或至少使用 bundleIdentifier ?? normalizedName 并在生成脚本里强制校验碰撞为 0。
如果将资源格式升级为新版本,可能需要将 SmartStartService.catalogVersion 从 2 升到 3。
但当前逻辑中:
store.smartStart.catalogVersion < catalogVersion
会触发 Smart Start 重新运行。发布前必须明确这是否是期望行为,否则可能让老用户再次被 Smart Start 打扰。
当前市场发布版暂不执行 notes 按语言拆分。
本版继续使用单 JSON 结构,优先完成:
下一版若执行 notes 按语言拆分,应采用双读兼容策略:
base catalog + notes.<current>.json
SmartStartUltimateDefaultCatalog.json
旧单文件失败时,再回退 legacy CSV。
为语言切换和用户备注保护,至少补充一种安全机制:
en、zh-Hans。SmartStartUltimateDefaultCatalog.noteFingerprints.json,只用于判断当前用户备注是否属于系统默认备注。{
"version": 3,
"notesResourceMode": "split-by-language"
}
但是否提升 SmartStartService.catalogVersion 必须单独评估,不能自动等同。
执行该拆分前,至少需要通过以下 QA:
构建产物检查
App bundle 内必须存在 base JSON、notes.zh-Hans.json、notes.en.json。声明支持的 notes 文件缺失时构建失败。
解析兼容
新格式可加载;缺 notes 文件可回退旧格式;损坏 notes 文件不会导致 Smart Start 空跑或崩溃。
首次启动一致性
中英文系统语言下,Smart Start 匹配数量、标签数量与旧格式一致。
语言切换安全
先用 zh-Hans 写入默认 note,再切 en,再切回 zh-Hans,系统默认 note 能更新;用户手写 note 不被覆盖。
fallback 链
当前语言无 note 时按 当前语言 -> en -> zh-Hans 命中;三者都无时不写 note。
join 数据质量
base entries 数、可匹配 bundle 数、有效 tag 数与旧 JSON 一致;notes join miss 为 0;join collision 为 0。
多语言备注质量
所有 notes 不超过 80 个 Unicode 字符;不以标点开头;不重复 App 名称;不是标签名或分类名拼接;缺失、空翻译、超限翻译进入 Translation QA 并阻断发布。
性能
冷启动和首次 makeDraft 不慢于旧版;语言切换懒加载不阻塞主线程。
建议拆成三个小版本或三个独立 PR:
生成器准备
新增 base JSON + per-language notes JSON 输出,同时保留旧单 JSON 输出;生成 join QA 和 Translation QA。
运行时双读
App 支持新旧两种格式,默认仍读取旧格式;验证兼容性和用户备注保护。
默认切换
QA 通过后,将默认读取切到新格式,并保留旧格式 fallback 至少一个版本。
本评估不改变多语言备注质量规则。
无论 notes 存在单文件还是按语言拆分,都必须遵守: