iOS 自製注音輸入法——以自建 librime.xcframework 為引擎,從 macOS Squirrel SPEC 移植,詞庫引用洋蔥純注音與洋蔥 Plus(oniondelta / Onion_Rime_Files),主打「貼近 Apple 原廠手感 + RIME 強大選字」。
左:注音鍵盤實際運作(內嵌組字「ㄋㄧ」→ 候選 你/尼/妳/呢…) 右:容器 App 設定
- Bundle:
com.frost.stoat(鍵盤com.frost.stoat.keyboard) - 平台:iOS 16.0+(iOS 26 視覺特性自動加載)
- 引擎:librime(自建 xcframework,含 librime-lua + octagram + predict)
- 詞庫:洋蔥純注音
bopomo_onion.schema.yaml+ 洋蔥 Plus 擴充詞組(phrases.chtp),預編譯.bin隨 App 打包
- 聲韻母亂序(free-order) — RIME 精髓。聲母、韻母、聲調不必照順序打,引擎自動還原正確字。
- 大千鍵位 ≡ QWERTY 實體鍵 — 同一顆鍵服務注音輸入;注音鍵上下划即輸入英文(ㄆ↔q、ㄇ↔a、ㄈ↔z…),不必切頁。
- 智慧候選排序 — octagram 語法模型(
contextual_suggestions)依上下文重排候選,越打越準。 - 預測候選 — 選字後接續預測下一詞。
- 注音內嵌輸入框(可開關) — 開:組字注音顯在打字的輸入框(marked text,像原廠);關:注音顯在候選列、跨宿主較快。⚙ 選單切換。
- 展開候選面板 — 點候選列右側 chevron,鍵盤區展開成扁平等寬格狀候選(列間細橫線分隔),再點收合。
- emoji 候選 — 打「哈哈哈」直接出 🤣。
- 顏文字候選 — 與輸入連動。
- 生僻字 tofu 過濾 — 字型無法顯示(豆腐格)的候選自動濾除。
- 候選無編號、原廠灰 chevron,視覺對齊系統鍵盤。
- 原廠風格變動高度 — 總高度隨列數變(注音最高、英文/123 較矮);鍵寬/鍵高像素對標原廠(注音列多、鍵略矮=原廠比例;英文鍵較高,§182–187)。
- 功能列空白鍵置中 — 注音/英文/123 三模式空白鍵皆置中(兩拇指等距);123 頁 Enter 加大。
- 英文 QWERTY 頁 — 對齊 iOS 原廠,含可選常駐數字列。
- 123 數字符號頁 — 半/全形依中英模式自動切換,亦可在設定強制。
- 表情/顏文字面板 — emoji 鍵為原廠線條笑臉圖示;面板水平(左右)捲動瀏覽、分類 chip、內建 ⌫(長按連刪)。emoji 集對標 iOS 26(Unicode 16.0)、原廠分類順序。
- iOS 26 圓角 — 鍵盤上緣與按鍵採連續(squircle)圓角。
- Liquid Glass 玻璃按鍵 — iOS 26 可選開關(預設關,原廠實心白鍵/灰功能鍵)。開啟後可再選 玻璃風格(霜面/透明)與 色調(無色/藍/灰/暖)。
- 色調與玻璃風格 — iOS 26 玻璃按鍵開啟時,⚙ 輸入選項提供「玻璃風格」(霜面
UIGlassEffect .regular/透明.clear)與「色調」(無色/藍/灰/暖)即時切換。
- ⌫ 長按連續刪除;空白鍵長按滑動移游標。
- 中/英快切鍵常駐功能列。
- 原廠按壓高亮動畫(按下即時、放開淡出)。
- 簡繁、全半形、標點切換。
- 第一列快捷列可開關(⚙)— idle 時的「標點」與「顏文字」兩段各自開/關;兩段全關時連空候選列一併收起、鍵盤自動變矮、不留空白帶。
- 不疊加自家動畫 — 高度變更全程非動畫,切 App 不會額外彈跳。
- 轉場交給系統 — 不在系統轉場期重繪介面,純讓系統 snapshot/轉場動畫處理,貼近原廠平順。
- App resume 後乾淨重套 — 掛
willEnterForegroundNotification,回前景後在轉場完成時校正高度。 - 誠實邊界:自訂鍵盤跨進程、只能在首繪後改高,首次呈現的微 flash 為 iOS 系統限制(Apple DTS 證實)、原生無法完全消除;App 切換的卡片動畫亦為系統行為。
- 鍵盤內建選項選單(⚙)— 側載重簽會使 App Group 失效,故選項直接存鍵盤本地,側載也可用。
- 自訂詞庫 / UserData — 容器 App 內可看可改個人詞庫。
- 免裝機部署 — bundle 內帶預編譯
.bin,prebuilt_data_dir直接指過去,裝置端免重建。
- 全程離線,無網路請求。
- 無語音輸入(iOS 自訂鍵盤沙盒無法錄音/叫起聽寫,已整段移除)。
- 個人詞庫僅存於裝置本地。
開發主線 line-0.1.228(版本 0.1.228),在 0.1.227 的鍵縫容錯與版面修正上,將中文候選、idle 快捷符號、標點推薦統一為常駐按鈕 pool,以 hidden/unhidden 切換取代 UIStackView 反覆 remove/add;真機量測顯示 CandidateApply P95 約降 34%、空候選 P95 約降 49%。已發行穩定版仍為 v0.1.225;另提供 iOS 18 風格變體:
| 風格 | git 分支 / tag | 鍵盤外觀 |
|---|---|---|
| iOS 26(預設) | line-0.1.228 / v0.1.228 |
Liquid Glass 半透材質、squircle 圓角、systemGray 語意色 |
| iOS 18 扁平 | v0.1.228 release 的 ios18 資產 |
實心底(systemGray4/5)、5pt circular 方鍵、外框圓角跟隨系統、配色全 SDK 語意、保留玻璃切換 |
兩風格僅差鍵盤外觀(由
KeyboardViewController.flatStyleIOS18flag 控制,iOS18 版唯一差此一行);輸入核心、emoji、詞庫(plustrim)、版面皆共用。目前維護:
line-0.1.228(v0.1.228);release 提供 iOS26/iOS18 × plustrim/lite/full 六檔 IPA。已封存:archive/line-0.1.120-frozen(§133 合併控制列版面)、archive/main-v0.1.120(舊基線);舊穩定 tagv0.1.141/v0.1.141-ios18、v0.1.183(階段七穩定版)、v0.1.215(RIME 全背景化穩定版)、v0.1.224(精簡聲母 row4 置中)、v0.1.225(原位大千)保留為歷史快照。iOS 18 風格在 iOS 26 裝置上以 flag 手動重現——iOS 不公開鍵盤鍵色、且 runtime 渲染由裝置 OS 決定,故無法靠 build SDK 切換;色彩一律取自 SDK
systemGray語意(跨版穩定=官方值),系統需圓角處(外框)以系統為優先。
各風格再分 full(Plus 全詞庫)/ plustrim(Plus 精選,0.1.183 穩定版採用)/ lite(純注音核心)三詞庫,見下方建置。
stoat-keyboard/
├─ OnionKB/ # Xcode 專案(容器 App + 鍵盤 extension 兩 target)
│ ├─ App/ # 容器 App(設定、詞庫管理、狀態)
│ ├─ Keyboard/ # 鍵盤 extension(KeyboardViewController…)
│ ├─ Shared/Rime/ # RimeBridge.mm(librime C API 的 ObjC++ 薄包裝)
│ └─ Scripts/ # select-variant.sh(選詞庫變體)、package-ipa.sh(→ IPA)
├─ RimeData/ # 打包用 active 詞庫(不入庫,由 select-variant.sh 生成)
│ ├─ shared/ # schema / 詞庫源(bopomo_onion.schema.yaml…)
│ └─ build/ # 預編譯 .bin(prism / table / reverse)
├─ RimeData-variants/ # 三詞庫變體(入庫=真相源):{shared,build}-{lite,plustrim,full}
├─ ios-build/ # librime.xcframework 建置(含 selftest)
└─ releases/ # 已封裝 IPA(gitignored,散佈走 GitHub Releases)
資料流:大千鍵 → keycode → RimeBridge → librime → 組字/候選/上字 → UI。
引擎與 UI 以 RimeEngine 協定解耦(真 RimeEngineLibrime / 後備 RimeEngineStub)。
模擬器(驗證編譯)
cd OnionKB
xcodebuild -project OnionKB.xcodeproj -scheme OnionKB \
-sdk iphonesimulator -configuration Debug \
ARCHS=arm64 ONLY_ACTIVE_ARCH=YES build選擇詞庫變體:純注音(lite)/ Plus(full)
本鍵盤提供三種詞庫版本,分別打包成獨立 IPA(不在 App 內即時切換——librime 全域重載會出字異常)。RimeData/build/ 不入庫,打包前用 select-variant.sh 從 RimeData-variants/ 的 build-full(Plus)/ build-plustrim(Plus 精選)/ build-lite(純注音)生成:
| 變體 | 名稱 | 詞庫 | IPA | 適用 |
|---|---|---|---|---|
| full | Plus | 純注音 + 81 萬 phrases.chtp 擴充詞組(table.bin 28MB) | 57MB | 詞組完整、對齊 Squirrel onionplus |
| plustrim | Plus 精選 | Plus 依 essay 語料頻率篩留 35.6 萬詞(table.bin 14MB,§175) | 38MB | 詞彙豐富又輕快、容量與流暢度平衡(0.1.183 起穩定版採用) |
| lite | 純注音 | 純注音核心(~118K,table.bin 7.5MB) | 26MB | 輕量、省記憶體 |
IPA 體積皆 0.1.225 實測。自 0.1.215 起打包時自容器 App 層剝除
predict_office.db+.gram(僅鍵盤 appex 執行期需要,−11.6MB 未壓縮,§222)。
三者皆 B 方案(bgc grammar,候選出「為」)+ librime 1.17.0(runtime 引擎版號;RimeData-variants/*/build.version 的 1.16.1 為預編譯詞庫時 macOS 端 librime 版號,屬資料層、兩者相容),且表情候選已接線(打「哈哈哈」候選列出 🤣,schema 掛 simplifier@emoji)。
變體 .bin 存於
RimeData-variants/(不在RimeData/內,避免 bundle folder reference 把兩變體都打包進 IPA)。
bash OnionKB/Scripts/select-variant.sh plustrim # 或 full / lite裝置 IPA(unsigned,側載重簽)
bash OnionKB/Scripts/select-variant.sh plustrim # 先選變體(plustrim / full / lite)
cd OnionKB
bash Scripts/package-ipa.sh # 產出 build/ipa/OnionKB.ipa以 AltStore/Sideloadly 等工具重簽安裝;裝後於 設定 → 一般 → 鍵盤 → 加入新鍵盤 → Stoat,並開「允許完全取用」以同步設定。
iOS 18 扁平風格版
兩種做法,擇一:
# 方法 A:切到已 baked flag 的分支(推薦)
git checkout v0.1.225-ios18 # 或 line-ios18-0.1.225 分支
bash OnionKB/Scripts/select-variant.sh plustrim # 穩定版詞庫(或 full / lite)
cd OnionKB && bash Scripts/package-ipa.sh
# 方法 B:在主線手動翻 flag
# 編輯 OnionKB/Keyboard/KeyboardViewController.swift:
# static let flatStyleIOS18 = true
# 再 select-variant + package-ipa差別僅鍵盤外觀(實心底/方鍵);詞庫、版面、功能皆同 iOS 26 版。
CHANGELOG.md— 由動工到最新版的時序紀錄,每里程碑附 Debug/設計 Insight。

