ページ

2010年2月5日金曜日

BlogAssistant(14) - Queueの導入: フォルダ監視(FSEvent)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

(前回)Cocoaの日々: BlogAssistant(13) - Queueの導入: plistの読み込みと CoreDataへの保存

次は FSEvent を使ってフォルダを監視し、自動的にplistを読み込むようにする。

FSEvent の使い方は以前紹介したことがある。
Cocoaの日々: FSEvent - フォルダを監視する

処理は QueueManager に記載する。

QueueManager.m

- (void)startObservingQueue
{
 if (fseventStream) {
  FSEventStreamStop(fseventStream);
  FSEventStreamInvalidate(fseventStream);
 }
 
 NSString* path = [[PathManager sharedManager] queuePath];
 NSArray* pathsToWatch = [NSArray arrayWithObjects:path, nil];
 void *selfPointer = (void*)self;
 FSEventStreamContext context = {0, selfPointer, NULL, NULL, NULL};
    NSTimeInterval latency = 1.0; /* Latency in seconds */
 
    /* Create the stream, passing in a callback */
 fseventStream = FSEventStreamCreate(NULL,
    &fsevents_callback,
    &context,
    (CFArrayRef)pathsToWatch,
    kFSEventStreamEventIdSinceNow,
    latency,
    kFSEventStreamCreateFlagNone /* Flags explained in reference */
    );

    /* Create the stream before calling this. */
 FSEventStreamScheduleWithRunLoop(fseventStream,
   CFRunLoopGetCurrent(),
   kCFRunLoopDefaultMode
   );
 
 FSEventStreamStart(fseventStream);
 
}

監視間隔は1秒とした。このメソッドをアプリケーション起動時に呼び出しておく。

コールバックされる関数はこんな感じ。
void fsevents_callback(
   ConstFSEventStreamRef streamRef,
   void *userData,
   size_t numEvents,
   void *eventPaths,
   const FSEventStreamEventFlags eventFlags[],
   const FSEventStreamEventId eventIds[])
{
 QueueManager* qm = (QueueManager*)userData;
 [qm loadFiles];
}

前回作成した -[QueueManager loadFiles] を呼び出すだけ。


さて実行してみよう。
適当なページでクリップすると
出た。いい感じだ。

なおコールバック関数は1回のクリップ毎に2回呼ばれる。これはプラグインが Queueフォルダ内に plistを作成した1回に加え、管理アプリが読み込み後にplistを削除する1回があるため。削除時にイベントを無視できればよいのだが FSEvent を見る限りではそこまでフィルタできないようだ。呼び出している loadFiles はフォルダ内にファイルがなければすぐに終わる処理なのでそんなに問題にはならないだろう。そのままとしておく。


ソースコード (GitHub)

xcatsan's BlogAssistant at 2010-02-05 - GitHub