12 KiB
12 KiB
多语言 + 多布局 + 默认皮肤联动技术分析与架构方案
1. 需求摘要
你最终要的功能是:
- 用户在主 App 切换国家/语言。
- 如果该语言有多个键盘布局(如西班牙语 QWERTY / AZERTY / QWERTZ),点击语言后进入布局选择页。
- 选择布局时,页面展示该语言对应键盘布局预览。
- 切换语言时,自动下发该国家默认皮肤(例如英文 -> 西班牙语,自动应用西班牙默认皮肤)。
2. 现有代码现状分析
2.1 多语言系统(已具备基础能力)
- 语言管理集中在
KBLocalizationManager,支持运行时切换、App 与扩展共享。 - 当前默认支持语言只有
en和zh-Hans。 - 主 App 启动时会设置
supportedLanguageCodes。
关键代码位置:
/Users/mac/Desktop/项目/公司/KeyBoard/Shared/KBLocalizationManager.h/Users/mac/Desktop/项目/公司/KeyBoard/Shared/KBLocalizationManager.m/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/AppDelegate.m
当前限制:
- 语言常量只有
KBLanguageCodeEnglish、KBLanguageCodeSimplifiedChinese。 Localizable.strings目前只有en、zh-Hans两套。- 工程
knownRegions仅包含en、zh-Hans、Base。
2.2 键盘布局系统(已具备 JSON 驱动,但尚未按“语言+变体”建模)
- 扩展键盘布局配置由
kb_keyboard_layout_config.json驱动。 KBKeyboardView通过KBKeyboardLayoutConfig读取letters / numbers / symbolsMore布局并构建按键。- 当前布局名是固定三套,不带语言维度。
关键代码位置:
/Users/mac/Desktop/项目/公司/KeyBoard/CustomKeyboard/Model/KBKeyboardLayoutConfig.h/Users/mac/Desktop/项目/公司/KeyBoard/CustomKeyboard/Model/KBKeyboardLayoutConfig.m/Users/mac/Desktop/项目/公司/KeyBoard/CustomKeyboard/Resource/kb_keyboard_layout_config.json/Users/mac/Desktop/项目/公司/KeyBoard/CustomKeyboard/View/KBKeyboardView.m
当前限制:
KBKeyboardView当前布局选择逻辑只区分字母/数字/符号页,不区分输入语言。buildKeysForLettersLayout里仍保留了 QWERTY 兜底硬编码路径。
2.3 主 App 设置入口(可扩展)
KBPersonInfoVC是现有“设置”页面,可作为语言入口的落点。- 该页面当前有三行:昵称、性别、用户 ID。
关键代码位置:
/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/Me/VC/KBPersonInfoVC.m/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/Me/V/KBPersonInfoItemCell.m
结论:
- 最小侵入方案是直接在
KBPersonInfoVC增加“Language / Keyboard Layout”行和跳转逻辑,不需要额外改主流程导航。
2.4 皮肤系统(已具备跨进程下发能力)
KBSkinManager负责应用主题并通过 Darwin 通知同步到扩展。KBSkinInstallBridge负责发布“待安装皮肤请求”、扩展侧消费并应用。- 扩展
KeyboardViewController+Theme已监听并消费皮肤安装通知,且有默认皮肤兜底逻辑。
关键代码位置:
/Users/mac/Desktop/项目/公司/KeyBoard/Shared/KBSkinManager.m/Users/mac/Desktop/项目/公司/KeyBoard/Shared/KBSkinInstallBridge.m/Users/mac/Desktop/项目/公司/KeyBoard/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Theme.m
当前限制:
pendingRequest只有单槽位(同一时刻只能保留一条待消费皮肤请求)。- 默认皮肤逻辑目前由扩展按系统明暗自动判断,不包含“按语言自动默认皮肤”策略。
2.5 与新语言相关的隐含影响点
- 联想词引擎与 trailing-word 提取仅识别
a-z,会影响西语/葡语重音字母。 - 部分 locale 转换逻辑仍是二分(中文/英文),例如
KBMyVM的fetchCancelAccountWarningWithCompletion。 - 个别网络模块存在硬编码
Accept-Language。
关键代码位置:
/Users/mac/Desktop/项目/公司/KeyBoard/CustomKeyboard/Manager/KBSuggestionEngine.m/Users/mac/Desktop/项目/公司/KeyBoard/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Suggestions.m/Users/mac/Desktop/项目/公司/KeyBoard/keyBoard/Class/Me/VM/KBMyVM.m/Users/mac/Desktop/项目/公司/KeyBoard/CustomKeyboard/Network/NetworkStreamHandler.m
3. 目标架构(核心原则)
3.1 核心原则
- 展示语言 与 输入语言/布局 解耦。
- 语言切换是“偏好中心事件”,布局与皮肤都由该事件驱动。
- 皮肤优先级明确,避免覆盖用户主动选择。
- 保持现有 JSON 布局机制,不推翻
KBKeyboardView主体。
3.2 模块划分
建议新增以下共享模块(放 Shared,主 App 与扩展都可用):
KBInputLanguageProfileManagerKBKeyboardLayoutPreferenceManagerKBDefaultSkinPolicyManager
3.2.1 KBInputLanguageProfileManager(语言元数据中心)
职责:
- 维护每个语言的能力描述(是否多布局、默认布局、默认皮肤 ID、布局列表)。
- 提供给主 App 设置页和扩展布局解析器统一读取。
建议数据模型(JSON/Plist 均可):
languageCodedisplayNameKeysupportsMultipleLayoutslayoutVariantsdefaultLayoutVariantdefaultSkinIddefaultSkinZipName
示例(结构示意):
{
"es": {
"supportsMultipleLayouts": true,
"layoutVariants": ["qwerty", "azerty", "qwertz"],
"defaultLayoutVariant": "qwerty",
"defaultSkinId": "lang_es_default",
"defaultSkinZipName": "lang_es_default"
},
"pt": {
"supportsMultipleLayouts": false,
"layoutVariants": ["qwerty"],
"defaultLayoutVariant": "qwerty",
"defaultSkinId": "lang_pt_default",
"defaultSkinZipName": "lang_pt_default"
}
}
3.2.2 KBKeyboardLayoutPreferenceManager(语言/布局偏好持久化)
职责:
- 存储用户当前输入语言与布局变体。
- 提供“切换语言后自动决定下一步”的能力。
- App 与扩展通过 App Group 共享。
建议存储键(App Group):
KBPref_InputLanguageCodeKBPref_LayoutVariantByLanguage(字典)KBPref_CurrentLayoutVariantKBPref_UpdatedAt
通知建议:
- 进程内通知:
KBKeyboardPreferenceDidChangeNotification - Darwin 通知:
com.loveKey.nyx.keyboard.preference.changed
3.2.3 KBDefaultSkinPolicyManager(默认皮肤策略)
职责:
- 在语言切换时决定是否自动套用默认皮肤。
- 防止覆盖用户主动自定义皮肤。
建议策略:
- 记录
skinSource:language_default/user_selected/shop_downloaded/system_default。 - 仅当当前皮肤来源是
language_default或system_default时,语言切换可自动覆盖。 - 若当前皮肤来源为
user_selected,默认不自动覆盖,除非产品要求强制覆盖。
4. 主流程设计
4.1 主 App:语言切换流程
- 用户在设置页选择语言(例如西班牙语)。
- 写入
KBLocalizationManager(UI 文案语言切换)。 - 查询
KBInputLanguageProfileManager: - 若
supportsMultipleLayouts = YES,跳转布局选择页。 - 若
supportsMultipleLayouts = NO,直接写默认布局并结束。 - 布局选择完成后,写
KBKeyboardLayoutPreferenceManager。 - 触发默认皮肤策略,必要时发布皮肤安装请求给扩展。
4.2 主 App:布局选择页(新页面)
页面职责:
- 展示该语言可选布局(西班牙语 3 选 1)。
- 展示对应键盘预览(可复用
kb_keyboard_layout_config.json生成静态预览,或使用简化绘制)。 - 点击保存后写偏好并返回。
建议页面命名:
KBKeyboardLayoutSelectVC
4.3 键盘扩展:偏好生效流程
viewWillAppear读取共享偏好(现有已读取语言,可在此处同时读取布局偏好)。KBKeyboardView通过 Resolver 决定当前要用的letters layout name。- 调用
reloadKeys重建按键。 - 若收到偏好变更通知(进程内/Darwin),动态刷新当前键盘。
4.4 皮肤联动流程
- 主 App 语言切换后,根据 profile 取
defaultSkinId/defaultSkinZipName。 - 调用
KBSkinInstallBridge publishBundleSkinRequestWithId发布请求。 - 扩展侧现有 Darwin observer 会消费请求并应用皮肤。
- 键盘立即主题刷新(现有链路已具备)。
5. 键盘布局建模升级方案
5.1 JSON 扩展方式
不改 KBKeyboardLayoutConfig 的基础结构,只扩展 layouts 命名约定:
letters_es_qwertyletters_es_azertyletters_es_qwertzletters_pt_qwertyletters_id_qwertyletters_zh_hant_qwerty(若繁体沿用 QWERTY)
数字与符号可先复用:
numberssymbolsMore
5.2 Resolver 规则
新增 KBKeyboardLayoutResolver:
- 输入参数:
languageCode + layoutVariant + panelType - 输出布局名:
- 字母面板:
letters_<lang>_<variant> - 数字/符号:先复用现有
numbers/symbolsMore
回退链:
letters_<lang>_<variant>letters_<lang>_qwertyletters- legacy(当前已存在)
6. UI 与交互建议(结合现有代码)
6.1 设置入口落点
直接在 KBPersonInfoVC 的 section0 新增两行:
LanguageKeyboard Layout(仅多布局语言显示,单布局语言可隐藏或置灰显示默认值)
优势:
- 改动集中在已有设置页,不新增复杂入口链路。
- 能快速验证需求闭环。
6.2 预览实现建议
- 第一阶段:静态预览图(开发快,风险低)。
- 第二阶段:用同一份 layout JSON 动态绘制预览(与真实键盘一致性最高)。
7. 风险与约束
KBSkinInstallBridge的 pending request 是单槽位,语言切换与商城皮肤下载并发时可能互相覆盖。- 当前扩展默认皮肤逻辑会在某些时机自动执行,需要避免与你的“语言默认皮肤”策略冲突。
- 联想词和字符识别是英文字母集合,西语/葡语输入体验会受影响。
- locale 透传接口当前存在中文/英文二分逻辑,新增语言后需统一改造为映射表。
8. 分阶段实施计划
阶段 A:基础设施
- 扩展
KBLocalizationManager支持es / pt / zh-Hant / id。 - 增加 4 套本地化资源并加入工程 region。
- 新建
KBInputLanguageProfileManager与配置文件。
阶段 B:设置页与偏好持久化
- 新建
KBKeyboardLayoutPreferenceManager。 - 在
KBPersonInfoVC增加语言入口。 - 新建布局选择页与预览页。
阶段 C:扩展键盘接入
- 新建
KBKeyboardLayoutResolver。 KBKeyboardView切换为按 Resolver 选布局名。- 为西班牙语补三套
letters布局定义。
阶段 D:默认皮肤联动
- 新建
KBDefaultSkinPolicyManager。 - 语言切换后根据 profile 下发默认皮肤请求。
- 引入
skinSource防止覆盖用户自定义皮肤。
阶段 E:体验完善
- 联想词与字符集支持重音字符。
- 统一 locale 映射(网络、订阅文案、接口参数)。
- 并发请求队列化(解决 pending 单槽位冲突)。
9. 测试建议
- 切换语言后 UI 文案是否全量生效(主 App + 扩展)。
- 西班牙语三布局切换是否即时生效。
- 语言切换时默认皮肤是否按策略生效。
- 用户自定义皮肤是否不会被错误覆盖。
- 扩展冷启动、前后台、键盘切换场景下偏好一致性。
- App Group 不可用/完全访问关闭时的降级行为。
10. 我建议的落地架构结论
- 保留现有三大基座:
KBLocalizationManager、KBKeyboardLayoutConfig、KBSkinInstallBridge。 - 新增“语言 profile + 偏好管理 + 皮肤策略”三层,作为编排层。
- 先打通“西班牙语多布局”闭环,再批量扩展到葡语/繁体/印尼语。
- 先保证正确性与一致性,再优化联想词与并发策略。