# macOS 14 全新資料夾權限確認機制對副廠輸入法的考驗 哪怕你沒有用 CloudKit 等手段加裝正二八經的 iCloud Drive 支援,也是可以操縱你的 App 對 iCloud 資料夾進行讀寫操作的。這在 macOS 13 為止的系統內都是 OK 的,但在 macOS 14 當中則會在首次存取時觸發一個確認視窗(下文簡稱「存取確認視窗」)、讓使用者決定該 App 是否可以存取之。 這個功能的出發點是好的,但卻觸發了 InputMethodKit 的一個非常恐怖的災難級使用體驗故障、能讓整個系統畫面持續好幾十秒「無限風火輪+失去操作響應」。於是,筆者撰寫了這篇文章、方便各位副廠輸入法開發者們繞過 macOS 的這個系統設計缺陷。 咱們藉由本文能做到的是:哪怕彈出了「存取確認視窗」,也不會觸發這個故障。 > 本文討論的 macOS 14 是 dev beta 6,可能涵蓋不到 macOS 14 在此之後的更新。 只要一款輸入法的輸入控制會話模組(IMKInputController 的子型別)在被 InputMethodKit 開了副本的時候彈出了「存取確認視窗」,那麼這個輸入控制會話副本就會失去響應。而每個輸入控制模組副本都是會有與自己對接的客體應用的(遵循 IMKTextInput 協定),這個客體也會跟著遭殃失去響應。更甚者,當你嘗試使用滑鼠點到其他的應用的時候,輸入法會把新的當前應用當作新客體、來試著開具新的輸入控制會話副本,而這又會讓新的客體失去響應。結果就是整個系統畫面失去響應的時間又變長了。 此時你只有三個選擇:一、先點一下「存取確認視窗」當中的任何一個按鈕,然後等六十秒、看看系統自己是否能從這個狀態脫離出去;二、用 SSH 連到這臺電腦上、執行「klllall ProcessName」殺掉這個輸入法的執行緒;三、強行斷電重新開機(真的會有很多人等不及了就這樣做)。 典型案例就是威注音輸入法(截至 3.5.3 版)。這是截至本文發文為止唯一一款經過 Sandbox 處理的、不會擅自聯網的副廠 macOS 中文輸入法,能滿足一些企業的資訊安全需求。但是,只要是你在升級 macOS 14 之前安裝了該輸入法、且辭典目錄設定在 iCloud Drive 資料夾內的話,當你升級系統到 macOS 14 之後,嘗試使用威注音輸入法時,會彈出這個「存取確認視窗」,然後整個系統畫面就都失去響應了。 威注音輸入法 3.5.4 解決了這個災難級惡性體驗故障。方法很簡單: 1. 將輸入法開啟時的資料載入流程從 AppDelegate.applicationDidFinishLaunching 挪到 AppDelegate.applicationWillFinishLaunching 當中、使**該流程的觸發時機早於任何輸入控制會話副本的建構**。 2. 取消了在這個環節的異步處理(威注音用的是 Grand Central Dispatch 異步),使**該流程的完成時間點**早於任何輸入控制會話副本的建構。 ![](https://hackmd.io/_uploads/S1B97wj62.jpg) 其實呢,理論上而言,還有一個可以介入的地方(只是筆者尚未動手測試過):輸入法的輸入控制會話副本的建構子是可以返回 nil 的。只要執行任何可能會觸發「存取確認視窗」的操作,就在執行該操作的這段時間內讓某個全局開關(暫時命名為「罷工開關」)保持開啟。然後修改輸入控制會話副本的建構子:只要罷工開關是開啟的,一律返回 nil、讓輸入控制會話副本無法建構。**只要輸入控制會話副本無法建構,那就不存在將任何客體應用拖死的可能**。 P.S.: 這讓筆者想起了 macOS 10.9 - 10.12 的某個故障:只要讓輸入法自身叫出 NSOpenPanel,就會出現同樣的「系統畫面全局失去響應、連帶任何碰過的客體應用都失去響應」的故障。幸好 Apple 在 macOS 10.13 High Sierra 當中把 NSOpenPanel 的這個故障給解決了。 $ EOF.