特定のフォルダーの変更を単に監視し、変更されたファイルのパスを出力するアプリを作成しようとしています。後で、変更されたファイルの処理を行います。ネイティブココアでこれを行うにはどうすればよいですか? http://developer.apple.com/library/mac/#featuredarticles/FileSystemEvents/_index.htmlにリストされているものを試しました
しかし、タスクを効果的に達成する方法がわかりません。
コードサンプルは大歓迎です。
特定のフォルダーの変更を単に監視し、変更されたファイルのパスを出力するアプリを作成しようとしています。後で、変更されたファイルの処理を行います。ネイティブココアでこれを行うにはどうすればよいですか? http://developer.apple.com/library/mac/#featuredarticles/FileSystemEvents/_index.htmlにリストされているものを試しました
しかし、タスクを効果的に達成する方法がわかりません。
コードサンプルは大歓迎です。
Peter Hoseyに よるfs-notifierをご覧ください。
@interface Notifier : NSObject {
NSArray *paths; //Actually just one.
FSEventStreamRef stream;
struct FSEventStreamContext context;
}
+ (id) notifierWithCallback:(FSEventStreamCallback)newCallback path:(NSString *)newPath;
- (id) initWithCallback:(FSEventStreamCallback)newCallback path:(NSString *)newPath;
- (void) start;
- (void) stop;
@end
#import "Notifier.h"
@implementation Notifier
+ (id) notifierWithCallback:(FSEventStreamCallback)newCallback path:(NSString *)newPath {
return [[[self alloc] initWithCallback:newCallback path:newPath] autorelease];
}
- (id) initWithCallback:(FSEventStreamCallback)newCallback path:(NSString *)newPath {
if((self = [super init])) {
paths = [[NSArray arrayWithObject:newPath] retain];
context.version = 0L;
context.info = newPath;
context.retain = (CFAllocatorRetainCallBack)CFRetain;
context.release = (CFAllocatorReleaseCallBack)CFRelease;
context.copyDescription = (CFAllocatorCopyDescriptionCallBack)CFCopyDescription;
stream = FSEventStreamCreate(kCFAllocatorDefault, newCallback, &context, (CFArrayRef)paths, kFSEventStreamEventIdSinceNow, /*latency*/ 1.0, kFSEventStreamCreateFlagUseCFTypes);
if (!stream) {
NSLog(@"Could not create event stream for path %@", newPath);
[self release];
return nil;
}
FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
}
return self;
}
- (void) dealloc {
[self stop];
FSEventStreamUnscheduleFromRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
CFRelease(stream);
[super dealloc];
}
- (void) start {
FSEventStreamStart(stream);
}
- (void) stop {
FSEventStreamStop(stream);
}
@end
#import "Notifier.h"
static void gotEvent(ConstFSEventStreamRef streamRef,
void *clientCallBackInfo,
size_t numEvents,
void *eventPaths,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[]);
int main (int argc, char **argv) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *paths = [[NSProcessInfo processInfo] arguments];
NSMutableArray *streams = [NSMutableArray arrayWithCapacity:[paths count]];
for (NSString *path in paths) {
[streams addObject:[Notifier notifierWithCallback:gotEvent path:path]];
}
[streams makeObjectsPerformSelector:@selector(start)];
CFRunLoopRun();
[pool drain];
return EXIT_SUCCESS;
}
static void gotEvent(ConstFSEventStreamRef stream,
void *clientCallBackInfo,
size_t numEvents,
void *eventPathsVoidPointer,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[]
) {
NSArray *eventPaths = eventPathsVoidPointer;
NSString *streamName = clientCallBackInfo;
NSLog(@"%@: %@", streamName, [eventPaths objectAtIndex:0UL]);
}
例は、あなたが望むことをするための基本的な方法です。
Using the FSEvents Frameworkドキュメントをご覧ください。起動して実行するために必要なすべてを教えてくれます。ここで提供するコード サンプルは、ドキュメントに記載されているものと同じです。