HI,
tell, not ask. Polling is very very bad.
With a little help from Objective-C (FSEvents) let the operating system tell you when a directory changes
¢ Create an Objective-C class named FSEDirectoryWatcher
¢ Replace the contents of the .h file with
[format]#import <Foundation/Foundation.h>
@class FSEDirectoryWatcher;
@protocol FSEDirectoryWatcherDelegate
- (void)directoryDidChange:(NSString *)path;
@end
@interface FSEDirectoryWatcher : NSObject
- (id)directoryWatcherWithPath:(NSString *)path delegate:(id)delegate;
@property (copy) NSString *directory;
@property (weak) id delegate;
@end[/format]
- Caution. The syntax highlighter ignores text in < > characters. Replace the weak line with
@property (weak) id<FSEDirectoryWatcherDelegate> delegate;
¢ Replace the contents of the .m file with
[format]#import “FSEDirectoryWatcher.h”
static void fileSystemEventCallback(ConstFSEventStreamRef streamRef, void *userData, size_t numEvents, void *eventPaths,
const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]);
@interface FSEDirectoryWatcher ()
{
dispatch_queue_t queue;
FSEventStreamRef stream;
}
@end
@implementation FSEDirectoryWatcher
- (id)directoryWatcherWithPath:(NSString *)path delegate:(id)delegate
{
return [[FSEDirectoryWatcher alloc] initWithPath:path delegate];
}
-
(id)initWithPath:(NSString *)path delegate:(id)delegate
{
self = [super init];
if (self) {
_directory = path;
_delegate = delegate;
queue = dispatch_queue_create(“com.myself.FSDirectoryWatcher”, DISPATCH_QUEUE_SERIAL);
}
return self;
}
-
(void) dealloc
{
[self stop];
}
-
(void)start
{
NSArray *pathsToWatch = @[self.directory];
FSEventStreamContext context = {0, (__bridge void )self, NULL, NULL, NULL};
CFAbsoluteTime latency = 3.0; / Latency in seconds */
stream = FSEventStreamCreate(NULL, &fileSystemEventCallback, &context, (__bridge CFArrayRef)pathsToWatch,
kFSEventStreamEventIdSinceNow, latency, kFSEventStreamCreateFlagUseCFTypes);
FSEventStreamSetDispatchQueue(stream, queue);
FSEventStreamStart(stream);
}
-
(void)stop
{
if (stream) {
FSEventStreamStop(stream);
FSEventStreamInvalidate(stream);
FSEventStreamRelease(stream);
stream = nil;
}
}
@end
static void fileSystemEventCallback(ConstFSEventStreamRef streamRef, void *userData, size_t numEvents, void *eventPaths,
const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) {
FSEDirectoryWatcher *directoryWatcher = (__bridge FSEDirectoryWatcher *)userData;
NSArray *paths = (__bridge NSArray *)eventPaths;
[paths enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (directoryWatcher.delegate) [directoryWatcher.delegate directoryDidChange:obj];
}];
}
[/format]
¢ On the AppleScriptObjC side create a property
property watcher : missing value
¢ And implement this delegate handler which is called when the directory contents change. Instead of the log command add your logic to move the files. The handler will also be called when items are removed so the check for empty directory is very important.
on directoryDidChange:filePath
log filePath
end directoryDidChange:
¢ Finally add this code to start the watcher
set watcher to current application's FSEDirectoryWatcher's alloc()'s initWithPath:"/Volumes/SSD/01/" delegate:me
watcher's |start|()