macOS 14 全新资料夹权限确认机制对副厂输入法的考验

468 阅读4分钟

哪怕你没有用 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 异步),使该流程的完成时间点早于任何输入控制会话副本的建构。

image.png

其实呢,理论上而言,还有一个可以介入的地方(只是笔者尚未动手测试过):输入法的输入控制会话副本的建构子是可以返回 nil 的。只要执行任何可能会触发「存取确认视窗」的操作,就在执行该操作的这段时间内让某个全局开关(暂时命名为「罢工开关」)保持开启。然后修改输入控制会话副本的建构子:只要罢工开关是开启的,一律返回 nil、让输入控制会话副本无法建构。只要输入控制会话副本无法建构,那就不存在将任何客体应用拖死的可能

P.S.: 这让笔者想起了 macOS 10.9 - 10.12 的某个故障:只要让输入法自身叫出 NSOpenPanel,就会出现同样的「系统画面全局失去响应、连带任何碰过的客体应用都失去响应」的故障。幸好 Apple 在 macOS 10.13 High Sierra 当中把 NSOpenPanel 的这个故障给解决了。

$ EOF.