前回の検証を元に SimpleCap にログイン時起動オプションを追加した。
(前回)Cocoaの日々: ログイン時にアプリケーションを自動的に起動する設定を行う(LaunchService/Shared File Lists を使う)
SimpleCap オプション
チェックを付けるとログイン項目が追加できた。
ソースコード
前回のコードに少し手を加えた。
PreferenceController.m
#pragma mark -
#pragma mark Autostart on login
- (BOOL)isEnableLoginItem
{
 BOOL is_enable = NO;
 CFURLRef url = (CFURLRef)[NSURL fileURLWithPath: [[NSBundle mainBundle] bundlePath]];
 LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
 UInt32 seedValue;
 NSArray  *loginItemsArray = (NSArray *)LSSharedFileListCopySnapshot(loginItems, &seedValue);
 for (id item in loginItemsArray)
 {  
  LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)item;
  if (LSSharedFileListItemResolve(itemRef, 0, (CFURLRef*) &url, NULL) == noErr)
  {
   if ([[(NSURL *)url path] hasPrefix:[[NSBundle mainBundle] bundlePath]]) {
    is_enable = YES;
    break;
   }
  }
 }
 [loginItemsArray release];
 CFRelease(loginItems);
 return is_enable;
}
- (void)enableLoginItem
{
 CFURLRef url = (CFURLRef)[NSURL fileURLWithPath: [[NSBundle mainBundle] bundlePath]];
 LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
 LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemLast, NULL, NULL, url, NULL, NULL);  
 if (item)
 {
  CFRelease(item);
 }
 CFRelease(loginItems);
}
- (void)disableLoginItem
{
 CFURLRef url = (CFURLRef)[NSURL fileURLWithPath: [[NSBundle mainBundle] bundlePath]];
 LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
 UInt32 seedValue;
 NSArray  *loginItemsArray = (NSArray *)LSSharedFileListCopySnapshot(loginItems, &seedValue);
 for (id item in loginItemsArray)
 {  
  LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)item;
  if (LSSharedFileListItemResolve(itemRef, 0, (CFURLRef*) &url, NULL) == noErr)
  {
   if ([[(NSURL *)url path] hasPrefix:[[NSBundle mainBundle] bundlePath]]) {
    LSSharedFileListItemRemove(loginItems, itemRef);
    break;
   }
  }
 }
 [loginItemsArray release];
 CFRelease(loginItems);
}
- (IBAction)clickAutostartCheckbox:(id)sender
{
 if ([sender intValue] == 1) {
  // add
  [self enableLoginItem];
 } else {
  // remove
  [self disableLoginItem];
 }
} 
自動起動するのはアプリ自身と分かっているので汎用的な要素を省いた。また表示する時点でチェックを付けるべきかどうかを判断する為のメソッド isEnableLoginItem を追加した。チェック表示を更新するタイミングとしては (1) General(一般)タブが選択されて表示される時 (2)プリファレンスウィンドウがキーウィンドウ(アクティブ)になる時、としてそれぞれのタイミングで最新の状態をチェックボックスに反映するようにした。チェックボックス反映用のメソッドをまず用意する。
- (void)updateToolbarOnGeneral
{
 if ([self isEnableLoginItem]) {
  [_autostart_checkbox setIntValue:1];
 } else {
  [_autostart_checkbox setIntValue:0];
 }
}
(1) のケースはタブが押された時のイベントハンドラ内で呼ぶ。
- (void)click:(id)sender
{
 [_window setTitle:[sender label]];
 NSString* item_identifier = [sender itemIdentifier];
 NSInteger index = 0;
 if ([item_identifier isEqualToString:TOOLBAR_GENERAL]) {
  index = 0;
  [self updateToolbarOnGeneral];
           :
(2) のケースは NSWindowDelegate プロトコルのメソッドを使う。
- (void)windowDidBecomeKey:(NSNotification *)notification
{
 NSString* item_identifier = [_toolbar selectedItemIdentifier];
 if ([item_identifier isEqualToString:TOOLBAR_GENERAL]) {
  [self updateToolbarOnGeneral];
 }
}
- - - -
細かいところで意外と時間を食ってしまった。


