ログイン時にアプリを起動させたい場合、ログイン項目に自アプリを登録する。
そのためにLaunchAtLoginControllerを使っていたが、これはsandboxからは使えない。
Mozketo/LaunchAtLoginController · GitHub
sandboxからシステム環境設定を変更するにはAppleScript経由で設定を行う。手順は以下。
・.entitlementsファイルのcom.apple.security.temporary-exception.apple-eventsにcom.apple.systemeventsを追加する。詳細は→In the App Store but Outside the Sandbox: Login Items – Artisan Technology Log
・addLoginItem.scptとdeleteLoginItem.scptをプロジェクトに追加する。
Build Phases>Copy Bundle Resourcesにも追加する。
addLoginItem.scpt
tell application "System Events" make login item at end with properties {path:"%@", kind:application} end tell
deleteLoginItem.scpt
tell application "System Events" get the name of every login item if login item "%@" exists then delete login item "%@" end if end tell
apple scriptをロードし、実行してログイン項目を追加または削除する。
- (void)setLaunchAtLogin:(BOOL)enabled { [self willChangeValueForKey:StartAtLoginKey]; NSString *appleScriptTemplate = [self appleScriptTemplateWithLaunchAtLogin:enabled]; NSString *appleScriptSource = [self appleScriptSourceWithLaunchAtLogin:enabled appleScriptTemplate:appleScriptTemplate]; NSAppleScript *appleScript = [[NSAppleScript alloc] initWithSource:appleScriptSource]; NSDictionary * scriptRunError = nil; [appleScript executeAndReturnError:&scriptRunError]; if (scriptRunError) { NSLog(@"Script run error: %@", [scriptRunError description]); } [self didChangeValueForKey:StartAtLoginKey]; } - (NSString *)appleScriptTemplateWithLaunchAtLogin:(BOOL)enabled { NSString* scriptName = enabled ? @"addLoginItem" : @"deleteLoginItem"; NSString * scriptPath = [[NSBundle mainBundle] pathForResource:scriptName ofType: @"scpt"]; NSError *scriptLoadError; NSString *appleScriptTemplate = [NSString stringWithContentsOfFile:scriptPath encoding:NSUTF8StringEncoding error:&scriptLoadError]; if (scriptLoadError) { NSLog(@"Script load error: %@", [scriptLoadError description]); } return appleScriptTemplate; } - (NSString *)appleScriptSourceWithLaunchAtLogin:(BOOL)enabled appleScriptTemplate:(NSString *)appleScriptTemplate { if (enabled) { return [NSString stringWithFormat:appleScriptTemplate, [[NSBundle mainBundle] bundlePath]]; } else { NSString *appName = [[NSRunningApplication currentApplication] localizedName]; return [NSString stringWithFormat:appleScriptTemplate, appName, appName]; } }