Skip to content

bug: 「システムのユーザ辞書」の読み込みがサンドボックスにより常に失敗する(FetchError error 1) #354

Description

@tomippe

現象

設定画面の「システムのユーザ辞書」で「読み込む」を押すと、~/Library/KeyboardServices/TextReplacements.db が実在していても次のエラーになります。

読み込みエラー: The operation couldn't be completed. (Core.SystemUserDictionaryHelper.FetchError error 1.)

error 1 は FetchError.fileNotExist です。

原因

3点あると思います。

  1. SystemUserDictionaryHelper.fetchEntries() が最初に FileManager.default.fileExists(atPath:) で存在確認していますが、App Sandbox下ではコンテナ外の ~/Library/KeyboardServices/ は stat 自体が拒否されるため、ファイルが実在しても false になります。その結果、NSOpenPanelで権限をもらうフォールバック(isReadableFile が false の場合の分岐)に到達する前に .fileNotExist を throw して終了します
  2. entitlements に com.apple.security.files.user-selected.read-only がないため、仮にパネルまで到達してもユーザーがフォルダを選択したアクセス権が付与されません
  3. promptUserForTextReplacementDirectory() の panel.directoryURL が FileManager.default.homeDirectoryForCurrentUser 起点ですが、サンドボックス内ではこれはコンテナ側のホームを指します

修正例(0.1.4ベースの自分用ビルドで動作確認済み)

  1. fileExists の事前guardをやめ、isReadableFile で読めない場合(サンドボックスで存在確認できない場合を含む)にNSOpenPanelを出す構成に変更
  2. entitlements に com.apple.security.files.user-selected.read-only を追加
  3. panel.directoryURL を URL(fileURLWithPath: "/Users/\(NSUserName())/Library/KeyboardServices", isDirectory: true) に変更

この修正で「読み込む」→ パネルで KeyboardServices フォルダを選択 → 読み込み成功、となることを確認しました(DB内40件が取り込まれました)。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions