diff --git a/CDEvents.h b/CDEvents.h index 76be0e1..4d92759 100644 --- a/CDEvents.h +++ b/CDEvents.h @@ -412,6 +412,44 @@ ignoreEventsFromSubDirs:(BOOL)ignoreEventsFromSubDirs excludeURLs:(NSArray *)exludeURLs streamCreationFlags:(CDEventsEventStreamCreationFlags)streamCreationFlags; +/** + * Returns an CDEvents object initialized with the given URLs to watch, URLs to exclude, whether events from sub-directories are ignored or not and schedules the watcher on the given run loop. + * + * @param URLs An array of URLs (NSURL) we want to watch. + * @param block The block which the CDEvents object executes when it recieves an event. + * @param queue Dispatch queue which the which the watcher should be schedueled on. + * @param sinceEventIdentifier Events that have happened after the given event identifier will be supplied. + * @param notificationLatency The (approximate) time intervall between notifications sent to the delegate. + * @param ignoreEventsFromSubDirs Wheter events from sub-directories of the watched URLs should be ignored or not. + * @param exludeURLs An array of URLs that we should ignore events from. Pass nil if none should be excluded. + * @param streamCreationFlags The event stream creation flags. + * @return An CDEvents object initialized with the given URLs to watch, URLs to exclude, whether events from sub-directories are ignored or not and run on the given run loop. + * @throws NSInvalidArgumentException if the parameter URLs is empty or points to nil. + * @throws NSInvalidArgumentException if delegateis nil. + * @throws CDEventsEventStreamCreationFailureException if we failed to create a event stream. + * + * @see initWithURLs:delegate: + * @see initWithURLs:delegate:onRunLoop: + * @see ignoreEventsFromSubDirectories + * @see excludedURLs + * @see CDEventsEventBlock + * @see FSEventStreamCreateFlags + * + * @discussion To ask for events "since now" pass the return value of + * currentEventIdentifier as the parameter sinceEventIdentifier. + * CDEventStreamCreationFailureException should be extremely rare. + * + * @since head + */ +- (id)initWithURLs:(NSArray *)URLs + block:(CDEventsEventBlock)block + queue:(dispatch_queue_t)queue +sinceEventIdentifier:(CDEventIdentifier)sinceEventIdentifier +notificationLantency:(CFTimeInterval)notificationLatency +ignoreEventsFromSubDirs:(BOOL)ignoreEventsFromSubDirs + excludeURLs:(NSArray *)exludeURLs +streamCreationFlags:(CDEventsEventStreamCreationFlags)streamCreationFlags; + #pragma mark Flush methods /** @name Flushing Events */ /** diff --git a/CDEvents.m b/CDEvents.m index dc91967..f4f73e1 100644 --- a/CDEvents.m +++ b/CDEvents.m @@ -64,6 +64,8 @@ @interface CDEvents () { FSEventStreamRef _eventStream; CDEventsEventStreamCreationFlags _eventStreamCreationFlags; + + dispatch_queue_t _queue; } // Redefine the properties that should be writeable. @@ -238,19 +240,72 @@ - (id)initWithURLs:(NSArray *)URLs return self; } +- (id)initWithURLs:(NSArray *)URLs + block:(CDEventsEventBlock)block + queue:(dispatch_queue_t)queue +sinceEventIdentifier:(CDEventIdentifier)sinceEventIdentifier +notificationLantency:(CFTimeInterval)notificationLatency +ignoreEventsFromSubDirs:(BOOL)ignoreEventsFromSubDirs + excludeURLs:(NSArray *)exludeURLs +streamCreationFlags:(CDEventsEventStreamCreationFlags)streamCreationFlags +{ + if (block == NULL || URLs == nil || [URLs count] == 0) { + [NSException raise:NSInvalidArgumentException + format:@"Invalid arguments passed to CDEvents init-method."]; + } + + if ((self = [super init])) { + _watchedURLs = [URLs copy]; + _excludedURLs = [exludeURLs copy]; + _eventBlock = block; + + _sinceEventIdentifier = sinceEventIdentifier; + _eventStreamCreationFlags = streamCreationFlags; + + _notificationLatency = notificationLatency; + _ignoreEventsFromSubDirectories = ignoreEventsFromSubDirs; + + _lastEvent = nil; + + _queue = queue; + + [self createEventStream]; + + FSEventStreamSetDispatchQueue(_eventStream, _queue); + if (!FSEventStreamStart(_eventStream)) { + [NSException raise:CDEventsEventStreamCreationFailureException + format:@"Failed to create event stream."]; + } + } + + return self; +} + #pragma mark NSCopying method - (id)copyWithZone:(NSZone *)zone { - CDEvents *copy = [[CDEvents alloc] initWithURLs:[self watchedURLs] - block:[self eventBlock] - onRunLoop:[NSRunLoop currentRunLoop] - sinceEventIdentifier:[self sinceEventIdentifier] - notificationLantency:[self notificationLatency] - ignoreEventsFromSubDirs:[self ignoreEventsFromSubDirectories] - excludeURLs:[self excludedURLs] - streamCreationFlags:_eventStreamCreationFlags]; - + CDEvents *copy; + if (!_queue) { + copy = [[CDEvents alloc] initWithURLs:[self watchedURLs] + block:[self eventBlock] + onRunLoop:[NSRunLoop currentRunLoop] + sinceEventIdentifier:[self sinceEventIdentifier] + notificationLantency:[self notificationLatency] + ignoreEventsFromSubDirs:[self ignoreEventsFromSubDirectories] + excludeURLs:[self excludedURLs] + streamCreationFlags:_eventStreamCreationFlags]; + } + else { + copy = [[CDEvents alloc] initWithURLs:[self watchedURLs] + block:[self eventBlock] + queue:_queue + sinceEventIdentifier:[self sinceEventIdentifier] + notificationLantency:[self notificationLatency] + ignoreEventsFromSubDirs:[self ignoreEventsFromSubDirectories] + excludeURLs:[self excludedURLs] + streamCreationFlags:_eventStreamCreationFlags]; + } return copy; } @@ -351,16 +406,20 @@ static void CDEventsCallback( // contain any trailing slash. NSURL *eventURL = [NSURL fileURLWithPath:[[eventPathsArray objectAtIndex:i] stringByStandardizingPath]]; NSString *eventPath = [eventURL path]; - - // Ignore all events except for the URLs we are explicitly watching. - if ([watcher ignoreEventsFromSubDirectories]) { - shouldIgnore = YES; - for (NSURL *url in watchedURLs) { - if ([[url path] isEqualToString:eventPath]) { - shouldIgnore = NO; - break; - } - } + NSString *eventDirectoryPath = [eventPath stringByDeletingLastPathComponent]; + + // Check if is directory + BOOL isDirectory = CFURLHasDirectoryPath((__bridge CFURLRef)eventURL); + + // Ignore all events except for the URLs we are explicitly watching. + if ([watcher ignoreEventsFromSubDirectories]) { + shouldIgnore = YES; + for (NSURL *url in watchedURLs) { + if ([[url path] isEqualToString:eventDirectoryPath] && !isDirectory) { + shouldIgnore = NO; + break; + } + } // Ignore all explicitly excludeded URLs (not required to check if we // ignore all events from sub-directories). } else if (excludedURLs != nil) { diff --git a/CDEvents.podspec b/CDEvents.podspec index 58bf4fc..55360d3 100644 --- a/CDEvents.podspec +++ b/CDEvents.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = "CDEvents" - s.version = "1.2.2" + s.version = "1.2.3" s.summary = "An Objective-C wrapper for Mac OS X’s FSEvents C API." s.homepage = "http://rastersize.github.com/CDEvents" s.license = "MIT" s.author = { "Aron Cedercrantz" => "aron@cedercrantz.se" } - s.source = { :git => "https://github.com/rastersize/CDEvents.git", :tag => "1.2.2" } + s.source = { :git => "https://github.com/rastersize/CDEvents.git", :tag => "1.2.3" } s.platform = :osx, "10.6" s.source_files = "*.{h,m}" s.framework = "CoreServices" diff --git a/OLD b/OLD new file mode 100644 index 0000000..e69de29