いつも細かい手順を忘れがちなので、macOSアプリで特権モードを利用する際の自分用メモ
プロジェクト作成
プロジェクトを作成し、アプリ本体と特権モードを動かすヘルパーツールを登録。
アプリ本体は通常のAPP、ヘルパーツールはCommandLineToolなど。
AppStoreは使わないので署名は「Developer ID Application」で行う。
追加したヘルパーツールに必要となるplistを追加。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>com.sample.apphelper</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>apphelper</string>
<key>CFBundleVersion</key>
<string>1.0</string>
</dict>
</plist>
ヘルパーツールとのインタラクティブな制御は古典的プロセス間通信を利用。
そろそろXPC Service化してもいいのかもしれない。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ServiceIPC</key>
<false/>
<key>OnDemand</key>
<false/>
<key>Label</key>
<string>com.sample.apphelper</string>
<key>Disabled</key>
<true/>
</dict>
</plist>
注意点
-
TARGETS->apphelper->TARGETS->apphelper->General->Identity->Identity
からapphelper.plist
ファイルを登録しておく
そもそもデフォルトで用意してくれても良さそうだが、単に追加しただけでは存在しないらしい。 -
Build Settingsの
Product build Identifier
とProductName
を一致させておく
これを見落としていて1日悩んだ...
ターゲット登録
appheler
をアプリ本体のTarget Membership
にチェック。
アプリ本体のBuild Phasesでヘルパーツールを関連づけ
-
Build Phases
->Dependencies
にヘルパーツールを追加 -
Build Phases
->Copy Files
に以下の設定を追加-
Copy Files
がない場合はPane左上の+ボタンからNew Copy Files Phase
しておく
-
Destination:Wrapper
Subpath:Contents/Library/LaunchServices
追加ボタン(+)を押してヘルパーツールを追加
ヘルパーツール側の設定
-
Build Settings
->Other Linker Flags
に以下の4行を追加
-sectcreate
__TEXT
__launchd_plist
$(SRCROOT)/${TARGET_NAME}/apphelper-Launchd.plist
ビルド(一回目)
この状態で一度プログラム全体をビルド。(これが重要)
署名交換
アプリ本体とヘルパーツールを連携させるために、互いの署名を設定し合う。
SMJobBlessUtil.pyというツールがサンプルにあるのでこちらを利用する。
使い方は簡単
SMJobBlessUtil.py setreq <アプリファイル名> <アプリのplistファイル名> < ヘルパーツールのplistファイル名>
アプリ本体、ヘルパーツールにそれぞれTools owned after installation
、SMAuthorizedClients
が追加されたら成功。
anchor apple generic and identifier "<ヘルパーツールのbundleid>" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "<AppID>")
anchor apple generic and identifier "<APPのbundleid>" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "<AppID>")/* exists */
この状態で再度ビルドを行う。
コマンドやビルドが失敗した場合は以下を確認
-
Bundle identifier
とBundle Name
があっているかどうか - 署名は適切か
さらに追加で、Sandboxが有効になっているとエラーになるので、entitlementsファイルでApp Sandbox:NO
としておくこと。
お疲れさまでした。