TL;DR
-
Web経由で受け渡した自作アプリを実行すると起動フォルダ(としてアクセスする先)が強制的に /private/var/folders/... のような場所になる
-
そのため起動フォルダに設定ファイルを置くようなアプリがファイルを読めない
-
アプリと設定ファイルを個別に他のフォルダにコピーすると読めるようになる
-
xattrコマンドを使う方法もある
典型的な状況
UnityでmacOS用のアプリを作ってビルド済みのものを配布することがよくあります。そのとき、以下のようにしてアプリと同じ場所の設定ファイルを読むようにするのも常套手段です。1
# if UNITY_STANDALONE_OSX
configfile = Application.dataPath + "/../../config.txt";
# else
configfile = Application.dataPath + "/../config.txt";
# endif
少し前のmacOSの場合これで普通に読めたのですが、最近のmacOS2は「ローカルでビルドしたものは読めるものの、それをzipにまとめてWeb経由で受け渡すと読めなくなる」という現象が発生します。おそらくセキュリティ的な理由で、ダウンロードしたアプリは任意のフォルダにアクセスできないようにして、代わりに/private/var/folders/...のようなサンドボックス的なフォルダにアクセスさせるようにしたのだと思います。
余談ですが、以前からダウンロードしたアプリは「開発元が未確認のため開けません」というダイアログが出ていました。これについてはシステム環境設定の「セキュリティとプライバシー」で「このまま開く」を選択することで開けるようになるのは広く知られていると思います。
今回のは、それをおこなっても解決できない問題です。
また、右クリックして「情報を見る」といった操作でセキュリティ関係の属性を見ても、ローカルでビルドしたファイルとWebから取得したファイルに違いは一切ありません。ユーザーが知り得ないフラグがどこかにあるようです。3
解決策
公式な情報やstackoverflowなどを検索しても情報が見つからなかったので、独自に見つけた解決策です。以下の手順でコピーして実行するとセキュリティが解除されて起動フォルダがアプリのフォルダになるようです。
- 新たなフォルダを作成する(例:new_folder)
- Finderからドラッグ&ドロップでアプリをnew_folderにコピーする
- Finderからドラッグ&ドロップで設定ファイルをnew_folderにコピーする
このとき、以下の点に注意してください。
- アプリと設定ファイルを同時にコピーすると解除されない
- cpコマンドでコピーすると解除されない
ザ・バッドノウハウといった感じの手順ですね。
追記
xattrコマンドを使う方法を教えてもらいました。コマンドライン派の人はこちらをどうぞ。
👍
— ほっと (@hotwatermorning) July 28, 2019
この問題って例えば先に xattr -d https://t.co/vMzKfWx4Ky.quarantine しても起動フォルダが/private/var/になっちゃうっぽいです?
(macOSはアプリの権限周り厳しいしどんどん仕組みも新しくなるので開発者目線で考えるとちょっと厄介ですよね・・・)
ターミナルで以下のコマンドを実行して「No such xattr」と表示されなければ、example.appにWebから取得したという意味の拡張属性がついています。
> xattr -p com.apple.quarantine example.app
以下のコマンドで拡張属性を削除することでexample.appが起動フォルダにアクセスできるようになりました。
> xattr -d com.apple.quarantine example.app
xattrコマンドについてはmanで説明が出ます。
> man xattr