三方输入法平台侧实现研究(iOS / Android / macOS / Windows)

8 阅读10分钟

一、各端架构与特点

1.1 iOS:App Extension 双进程

iOS 不允许替换系统输入法应用,只能通过 App Extension 提供键盘扩展。体系由两个独立 target 组成,运行在两个独立进程

flowchart TB
    A[容器 App 独立进程]
    B[键盘扩展 独立进程]
    A ---|App Group 共享容器| B

特点

  • 双进程隔离,无实时通信通道,只能走 App Group"留纸条"。
  • 扩展进程按需加载、随时被杀,冷启动频繁。
  • 内存硬限 30~60MB(jetsam 硬杀无回调)。
  • 联网需 Open Access + 用户授权。

1.2 Android:IME Service 双进程

Android 输入法是一个 InputMethodService,打包在普通 App 里。主 App 和输入法 Service 是双进程,同属一个 APK,由系统分别调度:

flowchart TB
    A[主 App 进程]
    B[输入法 Service 进程]
    A ---|ContentProvider SharedPreferences 文件| B

特点

  • 同 APK 双进程,靠系统调度隔离,无 App Extension 概念。
  • IMS 是系统关键服务,保活比 iOS 扩展强得多。
  • 联网启用即可,无 Full Access 二选一。
  • UI 自由度高,可自绘悬浮窗。

1.3 macOS:IMK 独立常驻进程

macOS 输入法用 Input Method Kit(IMK) 框架,是一个独立 .app,放到 /Library/Input Methods/ 下,系统设置里勾选即可:

flowchart TB
    A[输入法 app 独立常驻进程 IMKServer]
    B[当前 App 备忘录 微信等]
    A ---|IMK 协议 Mach 端口 IPC| B

特点

  • 输入法进程与当前 App 是双进程,通过 IMK/Mach 端口 IPC 通信(同 iOS/Android 的双进程模型,区别在 macOS 输入法进程常驻不重启)。
  • 一个输入法进程常驻服务所有 App,通过多个 IMK 会话与各 App 通信,会话切换时清理状态。
  • 无硬性内存上限,可全量载入词库、跑大模型。
  • 联网自由,无 Full Access 概念。
  • UI 自由度最高,候选窗口可任意位置浮动。
  • App Store 沙盒化输入法能力受限,非沙盒(如 Rime/Squirrel)走 dmg 分发。

1.4 Windows:TSF 进程内 DLL 注入

Windows 现代输入法基于 TSF(Text Services Framework),输入法以 DLL 形式被系统加载到 ctfmon.exe 或当前聚焦 App 进程中运行:

flowchart TB
    A[ctfmon exe 或 当前 App 进程 TSF 宿主]
    B[输入法 DLL 运行在此进程空间 默认进程内]
    A --- B

特点

  • 默认进程内:DLL 直接加载进当前聚焦 App,无 IPC,直接函数调用
  • ctfmon.exe 是 TSF 守护进程,托管输入法指示器、系统侧加载、无焦点场景。
  • 无硬性内存上限,无 Full Access / 启用授权概念。
  • 崩溃可能拖垮宿主 App,稳定性要求严苛。
  • 历史包袱重(兼容 IMM 老模型)。

1.5 四端架构对比速查表

维度iOSAndroidmacOSWindows
承载机制App ExtensionIME ServiceIMK 框架TSF
进程形态容器 App + 扩展双进程主 App + IMS 双进程独立 .app 常驻 + IPCDLL 注入宿主进程
进程关系双进程,App Group 通信双进程,同 APK双进程,IMK/Mach IPC进程内(默认),无 IPC
内存限制30~60MB 硬限数百 MB无硬上限无硬上限
联网能力需 Open Access + 授权启用即可自由自由
UI 自由度最低最高
权限引导痛苦(多步 + Full Access)中等简单简单
整体自由度最低

核心规律:移动端(iOS/Android)受沙盒和省电约束严格,桌面端(macOS/Windows)更接近传统输入法实现。iOS 是四端里限制最多的。


二、通信机制与限制

2.1 标准协议 + 系统中介(共性模型)

四端输入法都遵循同一个抽象模型:输入法和宿主 App 互不认识,只认平台定义的标准接口,系统在中间做路由

flowchart TB
    A[宿主 App 微信]
    B[输入法进程 搜狗]
    C[平台输入法管理器 系统进程]
    A ---|实现标准接口| C
    B ---|调用标准接口| C

宿主不关心用户用搜狗还是百度,输入法也不关心用户在微信还是备忘录——双方都只实现/调用协议,系统负责匹配。这带来三个好处:解耦(任意输入法服务任意 App)、安全(系统做权限边界)、一致性(行为统一)。

2.2 各端接口与能力差异

各端的标准接口不同,能力丰富度差异显著:

维度iOSAndroidmacOSWindows
标准接口UITextInput / textDocumentProxyInputConnectionNSTextInputClientITfContext / TSF COM
通信方向双向双向双向双向(直接调用)
上下文读取受限,常为 nil较完整完整(选区/富文本)完整(同进程)
富内容文本 + Emoji(图片受限)文本 + 图片(InputContentInfo)富文本富文本
反向通道配置声明 + 系统事件InputConnection 双向方法NSTextInputClient 协议直接调用宿主

双向通信是三端共性:宿主通过配置(密码框、键盘类型、自动纠错等)和系统事件(焦点变化、文本变化)告知输入法当前需求,输入法据此调整。差异在反向通道的丰富度:macOS 最丰富 > Android 中等 > iOS 较窄。

富内容能力差异

  • iOS:Emoji/颜文字是 Unicode 字符可直接上屏;图片/GIF 无法直接上屏,无通用 API,需 App 配合或剪贴板。
  • Android:InputContentInfo(API 25+)通用提交图片/GIF。
  • macOS/Windows:富文本直接支持。

2.3 Windows 特殊性:无 IPC,能读宿主数据

Windows 是四端里唯一默认进程内的——输入法 DLL 直接加载进当前聚焦 App 进程,和宿主共享地址空间,不需要 IPC,是直接函数调用

这带来一个本质差异:Windows 输入法技术上能读宿主 App 的内存、调它的函数、hook 它的行为——和宿主自己的代码能力几乎一样。而 iOS/Android/macOS 因进程隔离,输入法只能调协议规定的方法,读不到宿主内存。

能力Windows(进程内)iOS/Android/macOS(IPC)
读宿主内存✅ 直接读❌ 进程隔离
调宿主函数✅ 直接调❌ 只能调协议方法
Hook 宿主✅ 可注入❌ 沙盒禁止
操作宿主窗口✅ 直接操作❌ 只能通过协议

防御机制:数字签名、UAC 完整性级别隔离、系统级场景只允许系统输入法、敏感 App(银行/支付)主动屏蔽三方输入法。但平台层隔离弱,安全性主要靠厂商自觉和用户信任——这也是 Windows 输入法长期作为恶意软件载体的根本原因。


三、各端 SDK 与开发框架

3.1 iOS:UIKit 的 UIInputViewController

  • 核心类UIInputViewController(扩展基类)。
  • 通信对象textDocumentProxy(与当前 App 通信的唯一接口,insertText:deleteBackward、读取上下文)。
  • 补充词表requestSupplementaryLexiconWithCompletion:(系统脱敏后给的通讯录人名词表,无需 Open Access)。
  • 配置Info.plistRequestsOpenAccess 开关决定是否可联网/访问共享容器。
  • 开发语言:Swift / Objective-C(引擎核心可用 C/C++ 通过 ObjC++ 桥接)。
  • 分发:App Store,受 Guideline 4.x 输入法专项审计。

3.2 Android:InputMethodService + InputConnection

  • 核心类InputMethodService(输入法基类,处理按键、生命周期)。
  • 通信对象InputConnection(与当前 App 通信,commitTextdeleteSurroundingTextgetTextBeforeCursor,支持 InputContentInfo 提交图片)。
  • UIWindowManager.addView 自绘候选栏和键盘(可悬浮于任意 App 之上)。
  • 配置:manifest 声明 BIND_INPUT_METHOD 权限,用户在系统设置启用。
  • 开发语言:Java / Kotlin(引擎核心可用 C/C++ 通过 JNI 桥接)。
  • 分发:应用商店 / APK,无专项审计但受系统安全提示约束。

3.3 macOS:IMK 框架

  • 核心类IMKServer(输入法服务端,进程入口)、IMKInputController(处理按键、与当前 App 通信)。
  • 通信对象sender(当前 App 代理,insertText:replacementRange:selectedRangestringFromRange:)。
  • 候选窗口IMKCandidates(系统提供,也可自绘 NSWindow)。
  • 配置:放到 /Library/Input Methods/,系统设置勾选。
  • 开发语言:Objective-C / Swift(引擎核心可用 C/C++)。
  • 分发:App Store(沙盒化,能力受限)/ dmg 直接分发(非沙盒,如 Rime/Squirrel)。

3.4 Windows:TSF(COM 接口)+ ctfmon

  • 核心接口ITfTextInputProcessor(输入法注册入口)、ITfKeyEventSink(按键回调)、ITfCompositionSink(preedit 状态)、ITfContext(与当前 App 通信)。
  • 宿主进程ctfmon.exe(TSF 守护进程,托管指示器、系统侧加载、无焦点场景);普通 App 输入时 DLL 注入到当前聚焦 App 进程。
  • 候选窗口:自绘 HWND,可任意位置悬浮。
  • 配置:注册到 TSF 系统,安装即用,无启用授权概念。
  • 开发语言:C++(COM 接口,繁琐)。
  • 分发:exe / 应用商店,输入法 DLL 需签名。

3.5 语言与上手成本对比

主语言引擎桥接上手成本备注
iOSSwift / ObjCObjC++沙盒和 Full Access 是主要坑
AndroidJava / KotlinJNI碎片化是主要坑
macOSObjC / SwiftObjC++IMK 文档相对清晰
WindowsC++直接TSF/COM 繁琐,文档老旧

引擎核心统一用 C/C++ 实现,各端通过 ObjC++ / JNI / 直接调用桥接——这是跨端复用的基础。


四、跨端方案

4.1 引擎核心复用 + 平台壳独立

工业输入法(搜狗、百度、Google 拼音、Rime)的标准做法:一套 C/C++ 引擎核心 + 四套平台壳。引擎层(音节切分 + DAG + Viterbi + N-gram)完全跨端复用,只有平台 UI 和通信层各端独立实现:

flowchart TB
    CORE[共享 C Cpp 引擎核心]
    IOS[iOS 扩展 ObjC 桥接]
    AND[Android JNI 桥接]
    MAC[macOS IMK]
    WIN[Windows TSF]
    CORE --> IOS
    CORE --> AND
    CORE --> MAC
    CORE --> WIN

4.2 词库云同步

  • 本地词库:各端打包自己的二进制词库(格式可统一,详见内存优化篇)。
  • 云同步:通过账号体系跨端同步用户词。桌面端自由联网,移动端需注意 iOS 的 Open Access 限制。
  • 同步策略:用户词先写本地,下次启动时若发现 Open Access,再后台同步到云端。

4.3 现有方案参考

开源方案

  • Rime(中州韵):跨平台开源输入法框架,C++ 核心引擎 + 各平台前端。macOS Squirrel、Windows Weasel、Linux ibus-rime、Android Trime、iOS 仓输入法。高度可配置、不联网、隐私干净。

商业方案

  • 搜狗、百度、Google 拼音等:一套引擎核心 + 四端平台壳,账号体系 + 云同步用户词。

五、共性难点与选型建议

5.1 四端共性难点

无论哪个平台,输入法都要面对:

  1. 性能与延迟:按键到上屏延迟需控制在几十毫秒内,引擎必须高效。
  2. 生命周期与状态恢复:随时被唤起/切换/杀掉,状态必须可持久化恢复。
  3. 多场景适配:密码框、系统弹窗、全屏应用、多显示器/分屏,行为各不相同。
  4. 隐私合规:按键数据敏感,需明确告知用途,避免违规收集。
  5. 系统适配持续:每年系统大版本都会改输入法相关行为,需持续跟进。

各端特有难点:

  • iOS:进程隔离通信瓶颈、Full Access 取舍、隐私审计、权限引导漏斗。
  • Android:国产 ROM 碎片化、机型适配。
  • macOS:沙盒 vs 非沙盒取舍、Apple Silicon 双架构、系统级场景不可用。
  • Windows:TSF/COM 学习曲线陡、DLL 稳定性、安全软件误判、系统级场景需签名。

5.2 选型建议

单端优先

  • 想快速验证 / 用户量优先:Android 或 Windows,限制少、自由度高、引导简单。
  • 苹果生态用户:iOS + macOS 必做,但 iOS 是瓶颈。
  • 追求极致可控:Windows(非沙盒)或 macOS(非 App Store)。

跨端优先级

  • 引擎核心一次写好,四端复用,是性价比最高的投入。
  • 平台壳按用户量排序:iOS/Android 优先(移动端用户多),macOS/Windows 次之。
  • 词库和用户词云同步是跨端体验一致性的关键。

六、小结

四端输入法平台侧的核心差异在承载机制和自由度

  • iOS:App Extension 双进程,限制最多(内存、联网、UI 全受限),但生态封闭、用户付费意愿强。
  • Android:IME Service 双进程,限制中等,碎片化是主要痛点。
  • macOS:IMK 独立常驻进程,自由度高,沙盒化趋势带来取舍。
  • Windows:TSF 进程内 DLL 注入,自由度最高,但 COM 复杂、稳定性要求严苛、安全隔离弱。

通信机制上,三端(iOS/Android/macOS)都是独立进程 + IPC + 标准协议,Windows 是例外(进程内直接调用)。这导致 Windows 输入法能读宿主数据,安全模型最弱。

一句话总结:四端里 iOS 限制最严(双进程 + Full Access + 内存红线),Android 居中(双进程但碎片化),桌面端 macOS/Windows 最自由(独立进程/DLL、联网自由、UI 自由)。引擎核心可跨端复用,平台壳各端独立——这是工业输入法的标准跨端架构。