日々精進

新しく学んだことを書き留めていきます

sandbox化したアプリからログイン項目に自アプリを登録する

ログイン時にアプリを起動させたい場合、ログイン項目に自アプリを登録する。
そのために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];
    }
}