2011年2月16日水曜日

Cocoa ObjC タスクスイッチャもどき(3)他のアプリの起動、終了を感知する

タスクスイッチャなので、自分が起動している間に他のアプリが起動されたり終了されたりしたら、ちゃんとそれを感知しないと話にならない。

デベロッパドキュメントを読むと、NSWorkspaceクラスのNotificationCenterで、NSWorkspaceDidLaunchApplicationNotification、NSWorkspaceDidTerminateApplicationNotificationをObserveすればいいことがわかった。さっそく実装。

NSWorkspace *ws=[NSWorkspace sharedWorkspace];
 [[ws notificationCenter] addObserver:self selector:@selector(appLaunched:) name:NSWorkspaceDidLaunchApplicationNotification object:ws];
 [[ws notificationCenter] addObserver:self selector:@selector(appTermed:) name:NSWorkspaceDidTerminateApplicationNotification object:ws];

Observerの設定はこれでOK。あとは@selectorを書くだけ。

-(void)appLaunched:(NSNotification *)notification{
 
 NSRunningApplication* app=[[notification userInfo] objectForKey:@"NSWorkspaceApplicationKey"];
 
 [self addAppAndButton:app]; 
}
addAppAndButtonは実際にaddViewをするメソッドで、たいしたことはしていない。

-(void)addAppAndButton:(NSRunningApplication *)app{
 
 if([app bundleIdentifier]!=[[NSRunningApplication currentApplication] bundleIdentifier]){
  NSRect viewFrame=NSMakeRect(0, 0, 10,10);
  SPApp *sp=[[SPApp alloc] initWithRunningApp:app];
  MyView *buttonView=[[MyView alloc] initWithFrame:viewFrame runApp:sp];
  [view addSubview:buttonView];
  [buttonView release];
  [sp release];
 }
}

自分自身を拾わないために

if([app bundleIdentifier]!=[[NSRunningApplication currentApplication] bundleIdentifier]){

としているが、こんなんでいいのかな。

他のアプリが起動すればaddSubViewすればいいわけだが、終了したらどうするか。こっちのほうが難しいような感じがしたが、

-(void)appTermed:(NSNotification *)notification{
 NSRunningApplication* app=[[notification userInfo] objectForKey:@"NSWorkspaceApplicationKey"];
 NSArray *views = [view subviews];
 for( MyView * a_view in views){
  if([[a_view _app] _pid]==[app processIdentifier]){
   [a_view removeFromSuperview];
  }
 }
 
}

意外とこれだけで大丈夫のようだ。[a_view removeFromSuperview];のあとに「break;」を入れたほうがよりいいかな。deallocがうまくいっているかどうか、調べる方法をみつけなければ(^^;)。

本日わかったことはNotificationで通知されるuserInfoからObjectw取り出すやりかた。rubyで言うところのHashと同じ、とは知っていたが、実際に自分でKeyからObjectを指定して、うまくいくかどうかちょっとどきどき。

subViewを削除するのも[a_view removeFromSuperview];だけでいいとは。拍子抜けするほど簡単だ。
もしかしてObjCって、rubyくらいユーザフレンドリなのか?

Cocoaフレームワークに触りだしてから、毎日が異常に充実している。家に帰ってきてiMac起動させるのが待ち遠しくて仕方がない。職場のPCがWindowsマシンでよかった。Macだったら仕事もしないでプログラミングしているところだった。(^^;)

0 件のコメント:

コメントを投稿