• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

An Objective-C wrapper for Mac OS X’s FSEvents C API.


Commit MetaInfo

Révisionb0699d26646c7c51cd91f31a04f0f8b7f61a273a (tree)
l'heure2010-04-04 05:01:19
AuteurAron Cedercrantz <aron@cede...>
CommiterAron Cedercrantz

Message de Log

Merge branch 'release/1.0.0'

Change Summary

Modification

--- /dev/null
+++ b/CDEvent.h
@@ -0,0 +1,151 @@
1+/**
2+ * CDEvents
3+ *
4+ * Copyright (c) 2010 Aron Cedercrantz
5+ * http://github.com/rastersize/CDEvents/
6+ *
7+ * Permission is hereby granted, free of charge, to any person
8+ * obtaining a copy of this software and associated documentation
9+ * files (the "Software"), to deal in the Software without
10+ * restriction, including without limitation the rights to use,
11+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
12+ * copies of the Software, and to permit persons to whom the
13+ * Software is furnished to do so, subject to the following
14+ * conditions:
15+ *
16+ * The above copyright notice and this permission notice shall be
17+ * included in all copies or substantial portions of the Software.
18+ *
19+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26+ * OTHER DEALINGS IN THE SOFTWARE.
27+ */
28+
29+/**
30+ * @headerfile CDEvent.h CDEvents/CDEvent.h
31+ * A class that wraps the data from a FSEvents event callback.
32+ *
33+ * A class that wraps the data from a FSEvents event callback. Inspired and
34+ * based upon the open source project SCEvents created by Stuart Connolly
35+ * http://stuconnolly.com/projects/code/
36+ */
37+
38+#import <Foundation/Foundation.h>
39+#import <CoreServices/CoreServices.h>
40+
41+
42+/**
43+ * The event identifier type.
44+ *
45+ * @since 1.0.0
46+ */
47+typedef NSUInteger CDEventIdentifier;
48+
49+
50+/**
51+ * An Objective-C wrapper for a <code>FSEvents</code> event data.
52+ *
53+ * @note Inpired by <code>SCEvent</code> class of the <code>SCEvents</code> project by Stuart Connolly.
54+ * @note The class is immutable.
55+ *
56+ * @see FSEvents.h in CoreServices
57+ *
58+ * @since 1.0.0
59+ */
60+@interface CDEvent : NSObject <NSCoding, NSCopying> {
61+@private
62+ CDEventIdentifier _identifier;
63+ NSDate *_date;
64+ NSURL *_URL;
65+ FSEventStreamEventFlags _flags;
66+}
67+
68+#pragma mark Properties
69+/**
70+ * The event identifier.
71+ *
72+ * The event identifier as returned by <code>FSEvents</code>.
73+ *
74+ * @return The event identifier.
75+ *
76+ * @since 1.0.0
77+ */
78+@property (readonly) CDEventIdentifier identifier;
79+
80+/**
81+ * An approximate date and time the event occured.
82+ *
83+ * @return The approximate date and time the event occured.
84+ *
85+ * @since 1.0.0
86+ */
87+@property (readonly) NSDate *date;
88+
89+/**
90+ * The URL of the item which changed.
91+ *
92+ * @return The URL of the item which changed.
93+ *
94+ * @since 1.0.0
95+ */
96+@property (readonly) NSURL *URL;
97+
98+/**
99+ * The flags of the event.
100+ *
101+ * The flags of the event as returned by <code>FSEvents</code>.
102+ *
103+ * @return The flags of the event.
104+ *
105+ * @see FSEventStreamEventFlags
106+ *
107+ * @since 1.0.0
108+ */
109+@property (readonly) FSEventStreamEventFlags flags;
110+
111+#pragma mark Class object creators
112+
113+/**
114+ * Returns an <code>CDEvent</code> created with the given identifier, date, URL and flags.
115+ *
116+ * @param identifier The identifier of the the event.
117+ * @param date The date when the event occured.
118+ * @param URL The URL of the item the event concerns.
119+ * @param flags The flags of the event.
120+ * @return An <code>CDEvent</code> created with the given identifier, date, URL and flags.
121+ *
122+ * @see FSEventStreamEventFlags
123+ * @see initWithIdentifier:date:URL:flags:
124+ *
125+ * @since 1.0.0
126+ */
127++ (CDEvent *)eventWithIdentifier:(NSUInteger)identifier
128+ date:(NSDate *)date
129+ URL:(NSURL *)URL
130+ flags:(FSEventStreamEventFlags)flags;
131+
132+#pragma mark Init methods
133+/**
134+ * Returns an <code>CDEvent</code> object initialized with the given identifier, date, URL and flags.
135+ *
136+ * @param identifier The identifier of the the event.
137+ * @param date The date when the event occured.
138+ * @param URL The URL of the item the event concerns.
139+ * @param flags The flags of the event.
140+ * @return An <code>CDEvent</code> object initialized with the given identifier, date, URL and flags.
141+ * @see FSEventStreamEventFlags
142+ * @see eventWithIdentifier:date:URL:flags:
143+ *
144+ * @since 1.0.0
145+ */
146+- (id)initWithIdentifier:(NSUInteger)identifier
147+ date:(NSDate *)date
148+ URL:(NSURL *)URL
149+ flags:(FSEventStreamEventFlags)flags;
150+
151+@end
--- /dev/null
+++ b/CDEvent.m
@@ -0,0 +1,122 @@
1+/**
2+ * CDEvents
3+ *
4+ * Copyright (c) 2010 Aron Cedercrantz
5+ * http://github.com/rastersize/CDEvents/
6+ *
7+ * Permission is hereby granted, free of charge, to any person
8+ * obtaining a copy of this software and associated documentation
9+ * files (the "Software"), to deal in the Software without
10+ * restriction, including without limitation the rights to use,
11+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
12+ * copies of the Software, and to permit persons to whom the
13+ * Software is furnished to do so, subject to the following
14+ * conditions:
15+ *
16+ * The above copyright notice and this permission notice shall be
17+ * included in all copies or substantial portions of the Software.
18+ *
19+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26+ * OTHER DEALINGS IN THE SOFTWARE.
27+ */
28+
29+#import "CDEvent.h"
30+
31+
32+@implementation CDEvent
33+
34+#pragma mark Properties
35+@synthesize identifier = _identifier;
36+@synthesize date = _date;
37+@synthesize URL = _URL;
38+@synthesize flags = _flags;
39+
40+
41+#pragma mark Class object creators
42++ (CDEvent *)eventWithIdentifier:(NSUInteger)identifier
43+ date:(NSDate *)date
44+ URL:(NSURL *)URL
45+ flags:(FSEventStreamEventFlags)flags
46+{
47+ return [[[CDEvent alloc] initWithIdentifier:identifier
48+ date:date
49+ URL:URL
50+ flags:flags]
51+ autorelease];
52+}
53+
54+
55+#pragma mark Init/dealloc methods
56+
57+- (void)dealloc
58+{
59+ [_date release];
60+ [_URL release];
61+
62+ [super dealloc];
63+}
64+
65+- (id)initWithIdentifier:(NSUInteger)identifier
66+ date:(NSDate *)date
67+ URL:(NSURL *)URL
68+ flags:(FSEventStreamEventFlags)flags
69+{
70+ if ((self = [super init])) {
71+ _identifier = identifier;
72+ _flags = flags;
73+ _date = [date retain];
74+ _URL = [URL retain];
75+ }
76+
77+ return self;
78+}
79+
80+
81+#pragma mark NSCoding methods
82+
83+- (void)encodeWithCoder:(NSCoder *)aCoder
84+{
85+ [aCoder encodeObject:[NSNumber numberWithUnsignedInteger:[self identifier]] forKey:@"identifier"];
86+ [aCoder encodeObject:[NSNumber numberWithUnsignedInteger:[self flags]] forKey:@"flags"];
87+ [aCoder encodeObject:[self date] forKey:@"date"];
88+ [aCoder encodeObject:[self URL] forKey:@"URL"];
89+}
90+
91+- (id)initWithCoder:(NSCoder *)aDecoder
92+{
93+ self = [self initWithIdentifier:[[aDecoder decodeObjectForKey:@"identifier"] unsignedIntegerValue]
94+ date:[aDecoder decodeObjectForKey:@"date"]
95+ URL:[aDecoder decodeObjectForKey:@"URL"]
96+ flags:[[aDecoder decodeObjectForKey:@"flags"] unsignedIntegerValue]];
97+
98+ return self;
99+}
100+
101+#pragma mark NSCopying methods
102+
103+- (id)copyWithZone:(NSZone *)zone
104+{
105+ // We can do this since we are immutable.
106+ return [self retain];
107+}
108+
109+#pragma mark Public API
110+
111+- (NSString *)description
112+{
113+ return [NSString stringWithFormat:@"<%@: %p { identifier = %ld, URL = %@, flags = %ld, date = %@ }>",
114+ [self className],
115+ self,
116+ (unsigned long)[self identifier],
117+ [self URL],
118+ (unsigned long)[self flags],
119+ [self date]];
120+}
121+
122+@end
--- /dev/null
+++ b/CDEvents.h
@@ -0,0 +1,329 @@
1+/**
2+ * CDEvents
3+ *
4+ * Copyright (c) 2010 Aron Cedercrantz
5+ * http://github.com/rastersize/CDEvents/
6+ *
7+ * Permission is hereby granted, free of charge, to any person
8+ * obtaining a copy of this software and associated documentation
9+ * files (the "Software"), to deal in the Software without
10+ * restriction, including without limitation the rights to use,
11+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
12+ * copies of the Software, and to permit persons to whom the
13+ * Software is furnished to do so, subject to the following
14+ * conditions:
15+ *
16+ * The above copyright notice and this permission notice shall be
17+ * included in all copies or substantial portions of the Software.
18+ *
19+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26+ * OTHER DEALINGS IN THE SOFTWARE.
27+ */
28+
29+/**
30+ * @headerfile CDEvents.h CDEvents/CDEvents.h
31+ * A class that wraps the <code>FSEvents</code> C API.
32+ *
33+ * A class that wraps the <code>FSEvents</code> C API. Inspired and based
34+ * upon the open source project SCEvents created by Stuart Connolly
35+ * http://stuconnolly.com/projects/code/
36+ */
37+
38+#import <Foundation/Foundation.h>
39+#import <CoreServices/CoreServices.h>
40+
41+#import <CDEvents/CDEvent.h>
42+
43+@protocol CDEventsDelegate;
44+
45+#pragma mark -
46+#pragma mark CDEvents custom exceptions
47+extern NSString *const CDEventsEventStreamCreationFailureException;
48+
49+
50+#pragma mark -
51+#pragma mark Default values
52+/**
53+ * The default notificaion latency.
54+ *
55+ * @since 1.0.0
56+ */
57+#define CD_EVENTS_DEFAULT_NOTIFICATION_LATENCY (NSTimeInterval)3.0
58+
59+/**
60+ * The default value wheter events from sub directories should be ignored or not.
61+ *
62+ * @since 1.0.0
63+ */
64+#define CD_EVENTS_DEFAULT_IGNORE_EVENT_FROM_SUB_DIRS NO
65+
66+/**
67+ * The default event stream creation flags.
68+ *
69+ * @since 1.0.0
70+ */
71+const NSUInteger kCDEventsDefaultEventStreamFlags =
72+ (kFSEventStreamCreateFlagUseCFTypes |
73+ kFSEventStreamCreateFlagWatchRoot);
74+
75+
76+#pragma mark -
77+#pragma mark CDEvents interface
78+/**
79+ * An Objective-C wrapper for the <code>FSEvents</code> C API.
80+ *
81+ * @note Inpired by <code>SCEvents</code> class of the <code>SCEvents</code> project by Stuart Connolly.
82+ *
83+ * @see FSEvents.h in CoreServices
84+ *
85+ * @since 1.0.0
86+ */
87+@interface CDEvents : NSObject <NSCopying> {
88+@private
89+ id<CDEventsDelegate> _delegate;
90+
91+ FSEventStreamRef _eventStream;
92+ CFTimeInterval _notificationLatency;
93+
94+ CDEventIdentifier _sinceEventIdentifier;
95+ NSUInteger _eventStreamCreationFlags;
96+
97+ BOOL _ignoreEventsFromSubDirectories;
98+
99+ CDEvent *_lastEvent;
100+
101+ NSArray *_watchedURLs;
102+ NSArray *_excludedURLs;
103+}
104+
105+#pragma mark Properties
106+/**
107+ * The delegate object the <code>CDEvents</code> object calls when it recieves an event.
108+ *
109+ * @param delegate Delegate for the events object. <code>nil</code> removed the delegate.
110+ * @return The events's delegate.
111+ *
112+ * @since 1.0.0
113+ */
114+@property (assign) id<CDEventsDelegate> delegate;
115+
116+/**
117+ * The (approximate) time intervall between notifications sent to the delegate.
118+ *
119+ * @return The time intervall between notifications.
120+ *
121+ * @since 1.0.0
122+ */
123+@property (readonly) CFTimeInterval notificationLatency;
124+
125+/**
126+ * The event identifier from which events will be supplied to the delegate.
127+ *
128+ * @return The event identifier from which events will be supplied to the delegate.
129+ *
130+ * @since 1.0.0
131+ */
132+@property (readonly) CDEventIdentifier sinceEventIdentifier;
133+
134+/**
135+ * Wheter events from sub-directories of the watched URLs should be ignored or not.
136+ *
137+ * @param flag Wheter events from sub-directories of the watched URLs shouled be ignored or not.
138+ * @return <code>YES</code> if events from sub-directories should be ignored, otherwise <code>NO</code>.
139+ *
140+ * @since 1.0.0
141+ */
142+@property (assign) BOOL ignoreEventsFromSubDirectories;
143+
144+/**
145+ * The last event that occured and thas has been delivered to the delegate.
146+ *
147+ * @return The last event that occured and thas has been delivered to the delegate.
148+ *
149+ * @since 1.0.0
150+ */
151+@property (retain) CDEvent *lastEvent;
152+
153+/**
154+ * The URLs that we watch for events.
155+ *
156+ * @return An array of <code>NSURL</code> object for the URLs which we watch for events.
157+ *
158+ * @since 1.0.0
159+ */
160+@property (readonly) NSArray *watchedURLs;
161+
162+/**
163+ * The URLs that we should ignore events from.
164+ *
165+ * @return An array of <code>NSURL</code> object for the URLs which we want to ignore.
166+ * @discussion Events from concerning these URLs and there sub-directories will not be delivered to the delegate.
167+ *
168+ * @since 1.0.0
169+ */
170+@property (copy) NSArray *excludedURLs;
171+
172+
173+#pragma mark Event identifier class methods
174+/**
175+ * The current event identifier.
176+ *
177+ * @return The current event identifier.
178+ *
179+ * @see FSEventsGetCurrentEventId(void)
180+ *
181+ * @since 1.0.0
182+ */
183++ (CDEventIdentifier)currentEventIdentifier;
184+
185+/**
186+ * The last event identifier for the given device that was returned before the given date and time
187+ *
188+ * @param URL The URL of the item the event identifier is sought for, used to find the device.
189+ * @param time The date and time.
190+ * @return The last event identifier for the given URL that was returned before the given time
191+ *
192+ * @see FSEventsGetLastEventIdForDeviceBeforeTime(dev_t, CFAbsoluteTime)
193+ *
194+ * @since 1.1.0
195+ */
196++ (CDEventIdentifier)lastEventIdentifierForURL:(NSURL *)URL time:(NSDate *)time;
197+
198+
199+#pragma mark Init methods
200+/**
201+ * Returns an <code>CDEvents</code> object initialized with the given URLs to watch.
202+ *
203+ * @param URLs An array of URLs we want to watch.
204+ * @param delegate The delegate object the <code>CDEvents</code> object calls when it recieves an event.
205+ * @return An <code>CDEvents</code> object initialized with the given URLs to watch.
206+ * @throws NSInvalidArgumentException if <em>URLs</em> is empty or points to <code>nil</code>.
207+ * @throws NSInvalidArgumentException if <em>delegate</em>is <code>nil</code>.
208+ * @throws CDEventsEventStreamCreationFailureException if we failed to create a event stream.
209+ *
210+ * @see initWithURLs:delegate:onRunLoop:
211+ * @see initWithURLs:delegate:onRunLoop:notificationLantency:ignoreEventsFromSubDirs:excludeURLs:streamCreationFlags:
212+ * @see kCDEventsDefaultEventStreamFlags
213+ *
214+ * @discussion Calls startWatchingURLs:onRunLoop:notificationLantency:ignoreEventsFromSubDirs:excludeURLs:streamCreationFlags:
215+ * with <em>sinceEventIdentifier</em> with the current event identifier,
216+ * <em>notificationLatency</em> set to 3.0 seconds,
217+ * <em>ignoreEventsFromSubDirectories</em> set to <code>NO</code>,
218+ * <em>excludedURLs</em> to no URLs, the event stream creation flags will be set
219+ * to <code>kCDEventsDefaultEventStreamFlags</code> and schedueled on the
220+ * current run loop.
221+ *
222+ * @since 1.0.0
223+ */
224+- (id)initWithURLs:(NSArray *)URLs delegate:(id<CDEventsDelegate>)delegate;
225+
226+/**
227+ * Returns an <code>CDEvents</code> object initialized with the given URLs to watch and schedules the watcher on the given run loop.
228+ *
229+ * @param URLs An array of URLs we want to watch.
230+ * @param delegate The delegate object the <code>CDEvents</code> object calls when it recieves an event.
231+ * @param The run loop which the which the watcher should be schedueled on.
232+ * @return An <code>CDEvents</code> object initialized with the given URLs to watch.
233+ * @throws NSInvalidArgumentException if <em>URLs</em> is empty or points to <code>nil</code>.
234+ * @throws NSInvalidArgumentException if <em>delegate</em>is <code>nil</code>.
235+ * @throws CDEventsEventStreamCreationFailureException if we failed to create a event stream.
236+ *
237+ * @see initWithURLs:
238+ * @see initWithURLs:onRunLoop:notificationLantency:ignoreEventsFromSubDirs:excludeURLs:streamCreationFlags:
239+ * @see kCDEventsDefaultEventStreamFlags
240+ *
241+ * @discussion Calls startWatchingURLs:onRunLoop:notificationLantency:ignoreEventsFromSubDirs:excludeURLs:streamCreationFlags:
242+ * with <em>runLoop</em> set to the current run loop, <em>sinceEventIdentifier</em>
243+ * with the current event identifier, <em>notificationLatency</em> set to 3.0
244+ * seconds, <em>ignoreEventsFromSubDirectories</em> set to <code>NO</code>,
245+ * <em>excludedURLs</em> to no URLs and the event stream creation flags will be
246+ * set to <code>kCDEventsDefaultEventStreamFlags</code>.
247+ *
248+ * @since 1.0.0
249+ */
250+- (id)initWithURLs:(NSArray *)URLs
251+ delegate:(id<CDEventsDelegate>)delegate
252+ onRunLoop:(NSRunLoop *)runLoop;
253+
254+/**
255+ * Returns an <code>CDEvents</code> object initialized with the given URLs to watch, URLs to exclude, wheter events from sub-directories are ignored or not and schedules the watcher on the given run loop.
256+ *
257+ * @param URLs An array of URLs we want to watch.
258+ * @param delegate The delegate object the <code>CDEvents</code> object calls when it recieves an event.
259+ * @param runLoop The run loop which the which the watcher should be schedueled on.
260+ * @param sinceEventIdentifier Events that have happened after the given event identifier will be supplied.
261+ * @param notificationLatency The (approximate) time intervall between notifications sent to the delegate.
262+ * @param ignoreEventsFromSubDirs Wheter events from sub-directories of the watched URLs should be ignored or not.
263+ * @param exludeURLs An array of URLs that we should ignore events from. Pass <code>nil</code> if none should be excluded.
264+ * @param streamCreationFlags The event stream creation flags.
265+ * @return An <code>CDEvents</code> object initialized with the given URLs to watch, URLs to exclude, wheter events from sub-directories are ignored or not and run on the given run loop.
266+ * @throws NSInvalidArgumentException if the parameter URLs is empty or points to <code>nil</code>.
267+ * @throws NSInvalidArgumentException if <em>delegate</em>is <code>nil</code>.
268+ * @throws CDEventsEventStreamCreationFailureException if we failed to create a event stream.
269+ *
270+ * @see initWithURLs:
271+ * @see initWithURLs:onRunLoop:
272+ * @see ignoreEventsFromSubDirectories
273+ * @see excludedURLs
274+ * @see FSEventStreamCreateFlags
275+ *
276+ * @discussion To ask for events "since now" pass the return value of
277+ * currentEventIdentifier as the parameter sinceEventIdentifier.
278+ * CDEventStreamCreationFailureException should be extremely rare.
279+ *
280+ * @since 1.0.0
281+ */
282+- (id)initWithURLs:(NSArray *)URLs
283+ delegate:(id<CDEventsDelegate>)delegate
284+ onRunLoop:(NSRunLoop *)runLoop
285+sinceEventIdentifier:(CDEventIdentifier)sinceEventIdentifier
286+notificationLantency:(CFTimeInterval)notificationLatency
287+ignoreEventsFromSubDirs:(BOOL)ignoreEventsFromSubDirs
288+ excludeURLs:(NSArray *)exludeURLs
289+ streamCreationFlags:(NSUInteger)streamCreationFlags;
290+
291+#pragma mark Flush methods
292+
293+/**
294+ * Flushes the event stream synchronously.
295+ *
296+ * Flushes the event stream synchronously by sending events that have already occurred but not yet delivered.
297+ *
298+ * @see flushAsynchronously
299+ *
300+ * @since 1.0.0
301+ */
302+- (void)flushSynchronously;
303+
304+/**
305+ * Flushes the event stream asynchronously.
306+ *
307+ * Flushes the event stream asynchronously by sending events that have already occurred but not yet delivered.
308+ *
309+ * @see flushSynchronously
310+ *
311+ * @since 1.0.0
312+ */
313+- (void)flushAsynchronously;
314+
315+#pragma mark Misc methods
316+/**
317+ * Returns a NSString containing the description of the current event stream.
318+ *
319+ * @return A NSString containing the description of the current event stream.
320+ *
321+ * @see FSEventStreamCopyDescription
322+ *
323+ * @discussion For debugging only.
324+ *
325+ * @since 1.0.0
326+ */
327+- (NSString *)streamDescription;
328+
329+@end
--- /dev/null
+++ b/CDEvents.m
@@ -0,0 +1,284 @@
1+//
2+// CDEvents.m
3+// CDEvents
4+//
5+// Created by Aron Cedercrantz on 03/04/10.
6+// Copyright 2010 __MyCompanyName__. All rights reserved.
7+//
8+
9+#import "CDEvents.h"
10+
11+#import "CDEventsDelegate.h"
12+
13+#pragma mark CDEvents custom exceptions
14+NSString *const CDEventsEventStreamCreationFailureException = @"CDEventsEventStreamCreationFailureException";
15+
16+
17+#pragma mark -
18+#pragma mark Private API
19+// Private API
20+@interface CDEvents ()
21+
22+// The FSEvents callback function
23+static void CDEventsCallback(
24+ ConstFSEventStreamRef streamRef,
25+ void *callbackCtxInfo,
26+ size_t numEvents,
27+ void *eventPaths,
28+ const FSEventStreamEventFlags eventFlags[],
29+ const FSEventStreamEventId eventIds[]);
30+
31+// Creates and initiates the event stream.
32+- (void)createEventStream;
33+// Disposes of the event stream.
34+- (void)disposeEventStream;
35+
36+@end
37+
38+
39+#pragma mark -
40+#pragma mark Implementation
41+@implementation CDEvents
42+
43+#pragma mark Properties
44+@synthesize delegate = _delegate;
45+@synthesize notificationLatency = _notificationLatency;
46+@synthesize sinceEventIdentifier = _sinceEventIdentifier;
47+@synthesize ignoreEventsFromSubDirectories = _ignoreEventsFromSubDirectories;
48+@synthesize lastEvent = _lastEvent;
49+@synthesize watchedURLs = _watchedURLs;
50+@synthesize excludedURLs = _excludedURLs;
51+
52+
53+#pragma mark Event identifier class methods
54++ (CDEventIdentifier)currentEventIdentifier
55+{
56+ return (NSUInteger)FSEventsGetCurrentEventId();
57+}
58+
59+
60+#pragma mark Init/dealloc/finalize methods
61+- (void)dealloc
62+{
63+ [self disposeEventStream];
64+
65+ _delegate = nil;
66+
67+ [_lastEvent release];
68+ [_watchedURLs release];
69+ [_excludedURLs release];
70+
71+ [super dealloc];
72+}
73+
74+- (void)finalize
75+{
76+ [self disposeEventStream];
77+
78+ _delegate = nil;
79+
80+ [super finalize];
81+}
82+
83+- (id)initWithURLs:(NSArray *)URLs delegate:(id<CDEventsDelegate>)delegate
84+{
85+ return [self initWithURLs:URLs
86+ delegate:delegate
87+ onRunLoop:[NSRunLoop currentRunLoop]];
88+}
89+
90+- (id)initWithURLs:(NSArray *)URLs
91+ delegate:(id<CDEventsDelegate>)delegate
92+ onRunLoop:(NSRunLoop *)runLoop
93+{
94+ return [self initWithURLs:URLs
95+ delegate:delegate
96+ onRunLoop:runLoop
97+ sinceEventIdentifier:[CDEvents currentEventIdentifier]
98+ notificationLantency:CD_EVENTS_DEFAULT_NOTIFICATION_LATENCY
99+ ignoreEventsFromSubDirs:CD_EVENTS_DEFAULT_IGNORE_EVENT_FROM_SUB_DIRS
100+ excludeURLs:nil
101+ streamCreationFlags:kCDEventsDefaultEventStreamFlags];
102+}
103+
104+- (id)initWithURLs:(NSArray *)URLs
105+ delegate:(id<CDEventsDelegate>)delegate
106+ onRunLoop:(NSRunLoop *)runLoop
107+sinceEventIdentifier:(CDEventIdentifier)sinceEventIdentifier
108+notificationLantency:(CFTimeInterval)notificationLatency
109+ignoreEventsFromSubDirs:(BOOL)ignoreEventsFromSubDirs
110+ excludeURLs:(NSArray *)exludeURLs
111+ streamCreationFlags:(NSUInteger)streamCreationFlags
112+{
113+ if (delegate == nil || URLs == nil || [URLs count] == 0) {
114+ [NSException raise:NSInvalidArgumentException
115+ format:@"Invalid arguments passed to CDEvents init-method."];
116+ }
117+
118+ if ((self = [super init])) {
119+ _watchedURLs = [URLs copy];
120+ [self setExcludedURLs:exludeURLs];
121+ [self setDelegate:delegate];
122+
123+ _sinceEventIdentifier = sinceEventIdentifier;
124+ _eventStreamCreationFlags = streamCreationFlags;
125+
126+ _notificationLatency = notificationLatency;
127+ _ignoreEventsFromSubDirectories = ignoreEventsFromSubDirs;
128+
129+ _lastEvent = nil;
130+
131+ [self createEventStream];
132+
133+ FSEventStreamScheduleWithRunLoop(_eventStream,
134+ [runLoop getCFRunLoop],
135+ kCFRunLoopDefaultMode);
136+ if (!FSEventStreamStart(_eventStream)) {
137+ [NSException raise:CDEventsEventStreamCreationFailureException
138+ format:@"Failed to create event stream."];
139+ }
140+ }
141+
142+ return self;
143+}
144+
145+
146+#pragma mark NSCopying method
147+- (id)copyWithZone:(NSZone *)zone
148+{
149+ CDEvents *copy = [[CDEvents alloc] init];
150+
151+ copy->_delegate = _delegate;
152+ copy->_notificationLatency = [self notificationLatency];
153+ copy->_ignoreEventsFromSubDirectories = [self ignoreEventsFromSubDirectories];
154+ copy->_lastEvent = [[self lastEvent] retain];
155+ copy->_sinceEventIdentifier = _sinceEventIdentifier;
156+ copy->_watchedURLs = [[self watchedURLs] copyWithZone:zone];
157+ copy->_excludedURLs = [[self excludedURLs] copyWithZone:zone];
158+
159+ return copy;
160+}
161+
162+
163+#pragma mark Flush methods
164+- (void)flushSynchronously
165+{
166+ FSEventStreamFlushSync(_eventStream);
167+}
168+
169+- (void)flushAsynchronously
170+{
171+ FSEventStreamFlushAsync(_eventStream);
172+}
173+
174+
175+#pragma mark Misc methods
176+- (NSString *)description
177+{
178+ return [NSString stringWithFormat:@"<%@: %p { watchedURLs = %@ }>",
179+ [self className],
180+ self,
181+ [self watchedURLs]];
182+}
183+
184+- (NSString *)streamDescription
185+{
186+ CFStringRef streamDescriptionCF = FSEventStreamCopyDescription(_eventStream);
187+ NSString *returnString = [[NSString alloc] initWithString:(NSString *)streamDescriptionCF];
188+ CFRelease(streamDescriptionCF);
189+
190+ return [returnString autorelease];
191+}
192+
193+
194+#pragma mark Private API:
195+- (void)createEventStream
196+{
197+ FSEventStreamContext callbackCtx;
198+ callbackCtx.version = 0;
199+ callbackCtx.info = (void *)self;
200+ callbackCtx.retain = NULL;
201+ callbackCtx.release = NULL;
202+ callbackCtx.copyDescription = NULL;
203+
204+ NSMutableArray *watchedPaths = [NSMutableArray arrayWithCapacity:[[self watchedURLs] count]];
205+ for (NSURL *URL in [self watchedURLs]) {
206+ [watchedPaths addObject:[URL path]];
207+ }
208+
209+ _eventStream = FSEventStreamCreate(kCFAllocatorDefault,
210+ &CDEventsCallback,
211+ &callbackCtx,
212+ (CFArrayRef)watchedPaths,
213+ (FSEventStreamEventId)[self sinceEventIdentifier],
214+ [self notificationLatency],
215+ _eventStreamCreationFlags);
216+}
217+
218+- (void)disposeEventStream
219+{
220+ if (!(_eventStream)) {
221+ return;
222+ }
223+
224+ FSEventStreamStop(_eventStream);
225+ FSEventStreamInvalidate(_eventStream);
226+ FSEventStreamRelease(_eventStream);
227+ _eventStream = NULL;
228+}
229+
230+static void CDEventsCallback(
231+ ConstFSEventStreamRef streamRef,
232+ void *callbackCtxInfo,
233+ size_t numEvents,
234+ void *eventPaths,
235+ const FSEventStreamEventFlags eventFlags[],
236+ const FSEventStreamEventId eventIds[])
237+{
238+ CDEvents *watcher = (CDEvents *)callbackCtxInfo;
239+
240+ NSArray *excludedURLs = [watcher excludedURLs];
241+ NSArray *eventPathsArray = (NSArray *)eventPaths;
242+ BOOL shouldIgnore;
243+
244+ for (NSUInteger i = 0; i < numEvents; ++i) {
245+ shouldIgnore = NO;
246+
247+ NSString *eventPath = [eventPathsArray objectAtIndex:i];
248+
249+ if ([excludedURLs containsObject:[NSURL URLWithString:eventPath]]) {
250+ shouldIgnore = YES;
251+ } else if (excludedURLs != nil && [watcher ignoreEventsFromSubDirectories]) {
252+ for (NSURL *URL in excludedURLs) {
253+ if ([eventPath hasPrefix:[URL path]]) {
254+ shouldIgnore = YES;
255+ break;
256+ }
257+ }
258+ }
259+
260+ if (!shouldIgnore) {
261+ NSURL *eventURL = [NSURL URLWithString:eventPath];
262+
263+ CDEvent *event = [[CDEvent alloc] initWithIdentifier:eventIds[i]
264+ date:[NSDate date]
265+ URL:eventURL
266+ flags:eventFlags[i]];
267+
268+ if ([(id)[watcher delegate] conformsToProtocol:@protocol(CDEventsDelegate)]) {
269+ [[watcher delegate] URLWatcher:watcher eventOccurred:event];
270+ }
271+
272+ // Last event?
273+ if (i == (numEvents - 1)) {
274+ [watcher setLastEvent:event];
275+ }
276+
277+ [event release];
278+ }
279+ }
280+
281+
282+}
283+
284+@end
--- /dev/null
+++ b/CDEvents.xcodeproj/project.pbxproj
@@ -0,0 +1,473 @@
1+// !$*UTF8*$!
2+{
3+ archiveVersion = 1;
4+ classes = {
5+ };
6+ objectVersion = 45;
7+ objects = {
8+
9+/* Begin PBXBuildFile section */
10+ 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; };
11+ 9C6D03031166AFFA00343E46 /* CDEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6D03011166AFFA00343E46 /* CDEvent.h */; settings = {ATTRIBUTES = (Public, ); }; };
12+ 9C6D03041166AFFA00343E46 /* CDEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C6D03021166AFFA00343E46 /* CDEvent.m */; };
13+ 9C6D033D1166B32000343E46 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C6D033C1166B32000343E46 /* Foundation.framework */; };
14+ 9C6D04451166B35700343E46 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C6D04441166B35700343E46 /* CoreServices.framework */; };
15+ 9C6D051D1166BD5800343E46 /* CDEventsDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6D051C1166BD5800343E46 /* CDEventsDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
16+ 9C6D05241166BF5300343E46 /* CDEvents.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6D05221166BF5300343E46 /* CDEvents.h */; settings = {ATTRIBUTES = (Public, ); }; };
17+ 9C6D05251166BF5300343E46 /* CDEvents.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C6D05231166BF5300343E46 /* CDEvents.m */; };
18+ 9C6D06851167CC8600343E46 /* CDEvents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* CDEvents.framework */; };
19+ 9C6D06881167CCBD00343E46 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C6D06871167CCBD00343E46 /* main.m */; };
20+ 9C6D06B01167CE2000343E46 /* CDEventsTestAppController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C6D06AF1167CE2000343E46 /* CDEventsTestAppController.m */; };
21+ 9C6D06B91167CE8C00343E46 /* CDEvents.framework in Copy Bundle Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* CDEvents.framework */; };
22+/* End PBXBuildFile section */
23+
24+/* Begin PBXContainerItemProxy section */
25+ 9C6D06831167CC8300343E46 /* PBXContainerItemProxy */ = {
26+ isa = PBXContainerItemProxy;
27+ containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
28+ proxyType = 1;
29+ remoteGlobalIDString = 8DC2EF4F0486A6940098B216 /* CDEvents */;
30+ remoteInfo = CDEvents;
31+ };
32+/* End PBXContainerItemProxy section */
33+
34+/* Begin PBXCopyFilesBuildPhase section */
35+ 9C6D06BD1167CEAA00343E46 /* Copy Bundle Frameworks */ = {
36+ isa = PBXCopyFilesBuildPhase;
37+ buildActionMask = 2147483647;
38+ dstPath = "";
39+ dstSubfolderSpec = 10;
40+ files = (
41+ 9C6D06B91167CE8C00343E46 /* CDEvents.framework in Copy Bundle Frameworks */,
42+ );
43+ name = "Copy Bundle Frameworks";
44+ runOnlyForDeploymentPostprocessing = 0;
45+ };
46+/* End PBXCopyFilesBuildPhase section */
47+
48+/* Begin PBXFileReference section */
49+ 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
50+ 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
51+ 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
52+ 32DBCF5E0370ADEE00C91783 /* CDEvents_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDEvents_Prefix.pch; sourceTree = "<group>"; };
53+ 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
54+ 8DC2EF5B0486A6940098B216 /* CDEvents.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CDEvents.framework; sourceTree = BUILT_PRODUCTS_DIR; };
55+ 9C6D03011166AFFA00343E46 /* CDEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDEvent.h; sourceTree = "<group>"; };
56+ 9C6D03021166AFFA00343E46 /* CDEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDEvent.m; sourceTree = "<group>"; };
57+ 9C6D033C1166B32000343E46 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
58+ 9C6D04441166B35700343E46 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
59+ 9C6D051C1166BD5800343E46 /* CDEventsDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDEventsDelegate.h; sourceTree = "<group>"; };
60+ 9C6D05221166BF5300343E46 /* CDEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDEvents.h; sourceTree = "<group>"; };
61+ 9C6D05231166BF5300343E46 /* CDEvents.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDEvents.m; sourceTree = "<group>"; };
62+ 9C6D067D1167CC7400343E46 /* CDEventsTestApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CDEventsTestApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
63+ 9C6D067F1167CC7400343E46 /* CDEventsTestApp-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "CDEventsTestApp-Info.plist"; sourceTree = "<group>"; };
64+ 9C6D06871167CCBD00343E46 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
65+ 9C6D06AE1167CE2000343E46 /* CDEventsTestAppController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDEventsTestAppController.h; sourceTree = "<group>"; };
66+ 9C6D06AF1167CE2000343E46 /* CDEventsTestAppController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDEventsTestAppController.m; sourceTree = "<group>"; };
67+ D2F7E79907B2D74100F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
68+/* End PBXFileReference section */
69+
70+/* Begin PBXFrameworksBuildPhase section */
71+ 8DC2EF560486A6940098B216 /* Frameworks */ = {
72+ isa = PBXFrameworksBuildPhase;
73+ buildActionMask = 2147483647;
74+ files = (
75+ 9C6D033D1166B32000343E46 /* Foundation.framework in Frameworks */,
76+ 9C6D04451166B35700343E46 /* CoreServices.framework in Frameworks */,
77+ );
78+ runOnlyForDeploymentPostprocessing = 0;
79+ };
80+ 9C6D067B1167CC7400343E46 /* Frameworks */ = {
81+ isa = PBXFrameworksBuildPhase;
82+ buildActionMask = 2147483647;
83+ files = (
84+ 9C6D06851167CC8600343E46 /* CDEvents.framework in Frameworks */,
85+ );
86+ runOnlyForDeploymentPostprocessing = 0;
87+ };
88+/* End PBXFrameworksBuildPhase section */
89+
90+/* Begin PBXGroup section */
91+ 034768DFFF38A50411DB9C8B /* Products */ = {
92+ isa = PBXGroup;
93+ children = (
94+ 8DC2EF5B0486A6940098B216 /* CDEvents.framework */,
95+ 9C6D067D1167CC7400343E46 /* CDEventsTestApp.app */,
96+ );
97+ name = Products;
98+ sourceTree = "<group>";
99+ };
100+ 0867D691FE84028FC02AAC07 /* CDEvents */ = {
101+ isa = PBXGroup;
102+ children = (
103+ 08FB77AEFE84172EC02AAC07 /* Classes */,
104+ 32C88DFF0371C24200C91783 /* Other Sources */,
105+ 089C1665FE841158C02AAC07 /* Resources */,
106+ 9C6D06861167CC8E00343E46 /* TestApp */,
107+ 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */,
108+ 034768DFFF38A50411DB9C8B /* Products */,
109+ 9C6D067F1167CC7400343E46 /* CDEventsTestApp-Info.plist */,
110+ );
111+ name = CDEvents;
112+ sourceTree = "<group>";
113+ };
114+ 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = {
115+ isa = PBXGroup;
116+ children = (
117+ 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */,
118+ 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */,
119+ );
120+ name = "External Frameworks and Libraries";
121+ sourceTree = "<group>";
122+ };
123+ 089C1665FE841158C02AAC07 /* Resources */ = {
124+ isa = PBXGroup;
125+ children = (
126+ 8DC2EF5A0486A6940098B216 /* Info.plist */,
127+ 089C1666FE841158C02AAC07 /* InfoPlist.strings */,
128+ );
129+ name = Resources;
130+ sourceTree = "<group>";
131+ };
132+ 08FB77AEFE84172EC02AAC07 /* Classes */ = {
133+ isa = PBXGroup;
134+ children = (
135+ 9C6D03011166AFFA00343E46 /* CDEvent.h */,
136+ 9C6D03021166AFFA00343E46 /* CDEvent.m */,
137+ 9C6D05221166BF5300343E46 /* CDEvents.h */,
138+ 9C6D05231166BF5300343E46 /* CDEvents.m */,
139+ 9C6D051C1166BD5800343E46 /* CDEventsDelegate.h */,
140+ );
141+ name = Classes;
142+ sourceTree = "<group>";
143+ };
144+ 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = {
145+ isa = PBXGroup;
146+ children = (
147+ 9C6D033C1166B32000343E46 /* Foundation.framework */,
148+ 9C6D04441166B35700343E46 /* CoreServices.framework */,
149+ );
150+ name = "Linked Frameworks";
151+ sourceTree = "<group>";
152+ };
153+ 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = {
154+ isa = PBXGroup;
155+ children = (
156+ 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */,
157+ 0867D6A5FE840307C02AAC07 /* AppKit.framework */,
158+ D2F7E79907B2D74100F64583 /* CoreData.framework */,
159+ );
160+ name = "Other Frameworks";
161+ sourceTree = "<group>";
162+ };
163+ 32C88DFF0371C24200C91783 /* Other Sources */ = {
164+ isa = PBXGroup;
165+ children = (
166+ 32DBCF5E0370ADEE00C91783 /* CDEvents_Prefix.pch */,
167+ );
168+ name = "Other Sources";
169+ sourceTree = "<group>";
170+ };
171+ 9C6D06861167CC8E00343E46 /* TestApp */ = {
172+ isa = PBXGroup;
173+ children = (
174+ 9C6D06871167CCBD00343E46 /* main.m */,
175+ 9C6D06AE1167CE2000343E46 /* CDEventsTestAppController.h */,
176+ 9C6D06AF1167CE2000343E46 /* CDEventsTestAppController.m */,
177+ );
178+ path = TestApp;
179+ sourceTree = "<group>";
180+ };
181+/* End PBXGroup section */
182+
183+/* Begin PBXHeadersBuildPhase section */
184+ 8DC2EF500486A6940098B216 /* Headers */ = {
185+ isa = PBXHeadersBuildPhase;
186+ buildActionMask = 2147483647;
187+ files = (
188+ 9C6D03031166AFFA00343E46 /* CDEvent.h in Headers */,
189+ 9C6D051D1166BD5800343E46 /* CDEventsDelegate.h in Headers */,
190+ 9C6D05241166BF5300343E46 /* CDEvents.h in Headers */,
191+ );
192+ runOnlyForDeploymentPostprocessing = 0;
193+ };
194+/* End PBXHeadersBuildPhase section */
195+
196+/* Begin PBXNativeTarget section */
197+ 8DC2EF4F0486A6940098B216 /* CDEvents */ = {
198+ isa = PBXNativeTarget;
199+ buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "CDEvents" */;
200+ buildPhases = (
201+ 8DC2EF500486A6940098B216 /* Headers */,
202+ 8DC2EF520486A6940098B216 /* Resources */,
203+ 8DC2EF540486A6940098B216 /* Sources */,
204+ 8DC2EF560486A6940098B216 /* Frameworks */,
205+ );
206+ buildRules = (
207+ );
208+ dependencies = (
209+ );
210+ name = CDEvents;
211+ productInstallPath = "$(HOME)/Library/Frameworks";
212+ productName = CDEvents;
213+ productReference = 8DC2EF5B0486A6940098B216 /* CDEvents.framework */;
214+ productType = "com.apple.product-type.framework";
215+ };
216+ 9C6D067C1167CC7400343E46 /* CDEventsTestApp */ = {
217+ isa = PBXNativeTarget;
218+ buildConfigurationList = 9C6D06821167CC7500343E46 /* Build configuration list for PBXNativeTarget "CDEventsTestApp" */;
219+ buildPhases = (
220+ 9C6D06791167CC7400343E46 /* Resources */,
221+ 9C6D067A1167CC7400343E46 /* Sources */,
222+ 9C6D067B1167CC7400343E46 /* Frameworks */,
223+ 9C6D06BD1167CEAA00343E46 /* Copy Bundle Frameworks */,
224+ );
225+ buildRules = (
226+ );
227+ dependencies = (
228+ 9C6D06841167CC8300343E46 /* PBXTargetDependency */,
229+ );
230+ name = CDEventsTestApp;
231+ productName = CDEventsTestApp;
232+ productReference = 9C6D067D1167CC7400343E46 /* CDEventsTestApp.app */;
233+ productType = "com.apple.product-type.application";
234+ };
235+/* End PBXNativeTarget section */
236+
237+/* Begin PBXProject section */
238+ 0867D690FE84028FC02AAC07 /* Project object */ = {
239+ isa = PBXProject;
240+ buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "CDEvents" */;
241+ compatibilityVersion = "Xcode 3.1";
242+ hasScannedForEncodings = 1;
243+ mainGroup = 0867D691FE84028FC02AAC07 /* CDEvents */;
244+ productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
245+ projectDirPath = "";
246+ projectRoot = "";
247+ targets = (
248+ 8DC2EF4F0486A6940098B216 /* CDEvents */,
249+ 9C6D067C1167CC7400343E46 /* CDEventsTestApp */,
250+ );
251+ };
252+/* End PBXProject section */
253+
254+/* Begin PBXResourcesBuildPhase section */
255+ 8DC2EF520486A6940098B216 /* Resources */ = {
256+ isa = PBXResourcesBuildPhase;
257+ buildActionMask = 2147483647;
258+ files = (
259+ 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */,
260+ );
261+ runOnlyForDeploymentPostprocessing = 0;
262+ };
263+ 9C6D06791167CC7400343E46 /* Resources */ = {
264+ isa = PBXResourcesBuildPhase;
265+ buildActionMask = 2147483647;
266+ files = (
267+ );
268+ runOnlyForDeploymentPostprocessing = 0;
269+ };
270+/* End PBXResourcesBuildPhase section */
271+
272+/* Begin PBXSourcesBuildPhase section */
273+ 8DC2EF540486A6940098B216 /* Sources */ = {
274+ isa = PBXSourcesBuildPhase;
275+ buildActionMask = 2147483647;
276+ files = (
277+ 9C6D03041166AFFA00343E46 /* CDEvent.m in Sources */,
278+ 9C6D05251166BF5300343E46 /* CDEvents.m in Sources */,
279+ );
280+ runOnlyForDeploymentPostprocessing = 0;
281+ };
282+ 9C6D067A1167CC7400343E46 /* Sources */ = {
283+ isa = PBXSourcesBuildPhase;
284+ buildActionMask = 2147483647;
285+ files = (
286+ 9C6D06881167CCBD00343E46 /* main.m in Sources */,
287+ 9C6D06B01167CE2000343E46 /* CDEventsTestAppController.m in Sources */,
288+ );
289+ runOnlyForDeploymentPostprocessing = 0;
290+ };
291+/* End PBXSourcesBuildPhase section */
292+
293+/* Begin PBXTargetDependency section */
294+ 9C6D06841167CC8300343E46 /* PBXTargetDependency */ = {
295+ isa = PBXTargetDependency;
296+ target = 8DC2EF4F0486A6940098B216 /* CDEvents */;
297+ targetProxy = 9C6D06831167CC8300343E46 /* PBXContainerItemProxy */;
298+ };
299+/* End PBXTargetDependency section */
300+
301+/* Begin PBXVariantGroup section */
302+ 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = {
303+ isa = PBXVariantGroup;
304+ children = (
305+ 089C1667FE841158C02AAC07 /* English */,
306+ );
307+ name = InfoPlist.strings;
308+ sourceTree = "<group>";
309+ };
310+/* End PBXVariantGroup section */
311+
312+/* Begin XCBuildConfiguration section */
313+ 1DEB91AE08733DA50010E9CD /* Debug */ = {
314+ isa = XCBuildConfiguration;
315+ buildSettings = {
316+ ALWAYS_SEARCH_USER_PATHS = NO;
317+ COPY_PHASE_STRIP = NO;
318+ DYLIB_COMPATIBILITY_VERSION = 1;
319+ DYLIB_CURRENT_VERSION = 1;
320+ FRAMEWORK_VERSION = A;
321+ GCC_DYNAMIC_NO_PIC = NO;
322+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
323+ GCC_ENABLE_OBJC_GC = supported;
324+ GCC_MODEL_TUNING = G5;
325+ GCC_OPTIMIZATION_LEVEL = 0;
326+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
327+ GCC_PREFIX_HEADER = CDEvents_Prefix.pch;
328+ INFOPLIST_FILE = Info.plist;
329+ INSTALL_PATH = "@rpath";
330+ PRODUCT_NAME = CDEvents;
331+ WRAPPER_EXTENSION = framework;
332+ };
333+ name = Debug;
334+ };
335+ 1DEB91AF08733DA50010E9CD /* Release */ = {
336+ isa = XCBuildConfiguration;
337+ buildSettings = {
338+ ALWAYS_SEARCH_USER_PATHS = NO;
339+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
340+ DYLIB_COMPATIBILITY_VERSION = 1;
341+ DYLIB_CURRENT_VERSION = 1;
342+ FRAMEWORK_VERSION = A;
343+ GCC_ENABLE_OBJC_GC = supported;
344+ GCC_MODEL_TUNING = G5;
345+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
346+ GCC_PREFIX_HEADER = CDEvents_Prefix.pch;
347+ INFOPLIST_FILE = Info.plist;
348+ INSTALL_PATH = "@rpath";
349+ PRODUCT_NAME = CDEvents;
350+ WRAPPER_EXTENSION = framework;
351+ };
352+ name = Release;
353+ };
354+ 1DEB91B208733DA50010E9CD /* Debug */ = {
355+ isa = XCBuildConfiguration;
356+ buildSettings = {
357+ ARCHS = (
358+ x86_64,
359+ i386,
360+ );
361+ GCC_C_LANGUAGE_STANDARD = gnu99;
362+ GCC_OPTIMIZATION_LEVEL = 0;
363+ GCC_VERSION = "";
364+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
365+ GCC_WARN_UNUSED_VARIABLE = YES;
366+ ONLY_ACTIVE_ARCH = YES;
367+ PREBINDING = NO;
368+ RUN_CLANG_STATIC_ANALYZER = YES;
369+ SDKROOT = macosx10.5;
370+ };
371+ name = Debug;
372+ };
373+ 1DEB91B308733DA50010E9CD /* Release */ = {
374+ isa = XCBuildConfiguration;
375+ buildSettings = {
376+ ARCHS = (
377+ x86_64,
378+ i386,
379+ );
380+ GCC_C_LANGUAGE_STANDARD = gnu99;
381+ GCC_VERSION = "";
382+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
383+ GCC_WARN_UNUSED_VARIABLE = YES;
384+ PREBINDING = NO;
385+ RUN_CLANG_STATIC_ANALYZER = YES;
386+ SDKROOT = macosx10.5;
387+ };
388+ name = Release;
389+ };
390+ 9C6D06801167CC7500343E46 /* Debug */ = {
391+ isa = XCBuildConfiguration;
392+ buildSettings = {
393+ ALWAYS_SEARCH_USER_PATHS = NO;
394+ COPY_PHASE_STRIP = NO;
395+ GCC_DYNAMIC_NO_PIC = NO;
396+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
397+ GCC_ENABLE_OBJC_GC = unsupported;
398+ GCC_MODEL_TUNING = G5;
399+ GCC_OPTIMIZATION_LEVEL = 0;
400+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
401+ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
402+ INFOPLIST_FILE = "CDEventsTestApp-Info.plist";
403+ INSTALL_PATH = "$(HOME)/Applications";
404+ OTHER_LDFLAGS = (
405+ "-framework",
406+ Foundation,
407+ "-framework",
408+ AppKit,
409+ );
410+ PREBINDING = NO;
411+ PRODUCT_NAME = CDEventsTestApp;
412+ };
413+ name = Debug;
414+ };
415+ 9C6D06811167CC7500343E46 /* Release */ = {
416+ isa = XCBuildConfiguration;
417+ buildSettings = {
418+ ALWAYS_SEARCH_USER_PATHS = NO;
419+ COPY_PHASE_STRIP = YES;
420+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
421+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
422+ GCC_ENABLE_OBJC_GC = unsupported;
423+ GCC_MODEL_TUNING = G5;
424+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
425+ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
426+ INFOPLIST_FILE = "CDEventsTestApp-Info.plist";
427+ INSTALL_PATH = "$(HOME)/Applications";
428+ OTHER_LDFLAGS = (
429+ "-framework",
430+ Foundation,
431+ "-framework",
432+ AppKit,
433+ );
434+ PREBINDING = NO;
435+ PRODUCT_NAME = CDEventsTestApp;
436+ ZERO_LINK = NO;
437+ };
438+ name = Release;
439+ };
440+/* End XCBuildConfiguration section */
441+
442+/* Begin XCConfigurationList section */
443+ 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "CDEvents" */ = {
444+ isa = XCConfigurationList;
445+ buildConfigurations = (
446+ 1DEB91AE08733DA50010E9CD /* Debug */,
447+ 1DEB91AF08733DA50010E9CD /* Release */,
448+ );
449+ defaultConfigurationIsVisible = 0;
450+ defaultConfigurationName = Release;
451+ };
452+ 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "CDEvents" */ = {
453+ isa = XCConfigurationList;
454+ buildConfigurations = (
455+ 1DEB91B208733DA50010E9CD /* Debug */,
456+ 1DEB91B308733DA50010E9CD /* Release */,
457+ );
458+ defaultConfigurationIsVisible = 0;
459+ defaultConfigurationName = Release;
460+ };
461+ 9C6D06821167CC7500343E46 /* Build configuration list for PBXNativeTarget "CDEventsTestApp" */ = {
462+ isa = XCConfigurationList;
463+ buildConfigurations = (
464+ 9C6D06801167CC7500343E46 /* Debug */,
465+ 9C6D06811167CC7500343E46 /* Release */,
466+ );
467+ defaultConfigurationIsVisible = 0;
468+ defaultConfigurationName = Release;
469+ };
470+/* End XCConfigurationList section */
471+ };
472+ rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
473+}
--- /dev/null
+++ b/CDEventsDelegate.h
@@ -0,0 +1,71 @@
1+/**
2+ * SCEvents
3+ *
4+ * Copyright (c) 2010 Aron Cedercrantz
5+ * http://github.com/rastersize/CDEvents/
6+ *
7+ * Permission is hereby granted, free of charge, to any person
8+ * obtaining a copy of this software and associated documentation
9+ * files (the "Software"), to deal in the Software without
10+ * restriction, including without limitation the rights to use,
11+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
12+ * copies of the Software, and to permit persons to whom the
13+ * Software is furnished to do so, subject to the following
14+ * conditions:
15+ *
16+ * The above copyright notice and this permission notice shall be
17+ * included in all copies or substantial portions of the Software.
18+ *
19+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26+ * OTHER DEALINGS IN THE SOFTWARE.
27+ */
28+
29+/**
30+ * @headerfile CDEventsDelegate.h CDEvents/CDEventsDelegate.h
31+
32+ *
33+ * A protocol that that delegates of CDEvents conform to. Inspired and based
34+ * upon the open source project SCEvents created by Stuart Connolly
35+ * http://stuconnolly.com/projects/code/
36+ */
37+
38+@class CDEvents;
39+@class CDEvent;
40+
41+
42+/**
43+ * The CDEventsDelegate protocol defines the required methods implemented by delegates of CDEvents objects.
44+ *
45+ * @see CDEvents
46+ * @see CDevent
47+ *
48+ * @since 1.0.0
49+ */
50+@protocol CDEventsDelegate
51+
52+@required
53+/**
54+ * The method called by the <code>CDEvents</code> object on its delegate object.
55+ *
56+ * @param URLWatcher The <code>CDEvents</code> object which the event was recieved thru.
57+ * @param event The event data.
58+ *
59+ * @see CDEvents
60+ * @see CDevent
61+ *
62+ * @discussion Conforming objects' implementation of this method will be called
63+ * whenever an event occurs. The instance of CDEvents which received the event
64+ * and the event itself are passed as parameters.
65+ *
66+ * @since 1.0.0
67+ */
68+- (void)URLWatcher:(CDEvents *)URLWatcher eventOccurred:(CDEvent *)event;
69+
70+@end
71+
--- /dev/null
+++ b/CDEventsTestApp-Info.plist
@@ -0,0 +1,28 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+<plist version="1.0">
4+<dict>
5+ <key>CFBundleDevelopmentRegion</key>
6+ <string>English</string>
7+ <key>CFBundleExecutable</key>
8+ <string>${EXECUTABLE_NAME}</string>
9+ <key>CFBundleIdentifier</key>
10+ <string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
11+ <key>CFBundleInfoDictionaryVersion</key>
12+ <string>6.0</string>
13+ <key>CFBundlePackageType</key>
14+ <string>APPL</string>
15+ <key>CFBundleShortVersionString</key>
16+ <string>1.0</string>
17+ <key>CFBundleSignature</key>
18+ <string>????</string>
19+ <key>CFBundleVersion</key>
20+ <string>1</string>
21+ <key>LSMinimumSystemVersion</key>
22+ <string>${MACOSX_DEPLOYMENT_TARGET}</string>
23+ <key>NSMainNibFile</key>
24+ <string>MainMenu</string>
25+ <key>NSPrincipalClass</key>
26+ <string>NSApplication</string>
27+</dict>
28+</plist>
--- /dev/null
+++ b/CDEvents_Prefix.pch
@@ -0,0 +1,7 @@
1+//
2+// Prefix header for all source files of the 'CDEvents' target in the 'CDEvents' project.
3+//
4+
5+#ifdef __OBJC__
6+ #import <Foundation/Foundation.h>
7+#endif
--- /dev/null
+++ b/English.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
1+/* Localized versions of Info.plist keys */
2+
--- /dev/null
+++ b/Info.plist
@@ -0,0 +1,28 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+<plist version="1.0">
4+<dict>
5+ <key>CFBundleDevelopmentRegion</key>
6+ <string>English</string>
7+ <key>CFBundleExecutable</key>
8+ <string>${EXECUTABLE_NAME}</string>
9+ <key>CFBundleIconFile</key>
10+ <string></string>
11+ <key>CFBundleIdentifier</key>
12+ <string>com.cedercrantz.${PRODUCT_NAME:rfc1034Identifier}</string>
13+ <key>CFBundleInfoDictionaryVersion</key>
14+ <string>6.0</string>
15+ <key>CFBundleName</key>
16+ <string>${PRODUCT_NAME}</string>
17+ <key>CFBundlePackageType</key>
18+ <string>FMWK</string>
19+ <key>CFBundleShortVersionString</key>
20+ <string>1.0</string>
21+ <key>CFBundleSignature</key>
22+ <string>????</string>
23+ <key>CFBundleVersion</key>
24+ <string>1</string>
25+ <key>NSPrincipalClass</key>
26+ <string></string>
27+</dict>
28+</plist>
--- /dev/null
+++ b/README.mdown
@@ -0,0 +1,17 @@
1+# CDEvents #
2+
3+## What is this? ##
4+It's an Objective-C wrapper for Mac OS X's [FSEvents C API](http://developer.apple.com/mac/library/documentation/Darwin/Reference/FSEvents_Ref/FSEvents_h/index.html). Inspired and based upon the ([MIT-licensed]((http://www.opensource.org/licenses/mit-license.php)) open source project [SCEvents](http://stuconnolly.com/projects/code/) created by [Stuart Connolly](http://stuconnolly.com/).
5+
6+## Requirements ##
7+Requires Mac OS X 10.5, since FSEvents were introduced in 10.5, and an Intel CPU. Supports both manual memory management and garbage collection.
8+
9+## What differentiates CDEvents from SCEvents then? ##
10+Not all that much but a litle. First of all all classes and protocols are prefixed with `CD` instead of `SC`, I hope that won't be to hard to remember? Secondly `CDEvent` (the event data wrapper-class) is immutable in contrast to `SCEvent` which is mutable. The next reason, this is the initial reason why I decided to rewrite `SCEvents`, being that the class `SCEvents`' is a singleton. I couldn't find a good reason as to why it had been designed this way and for my project an ordinary `alloc`/`init` route would be a better choise.
11+
12+Another difference between `CDEvents` and `SCEvents` is that `CDEvents` is available for both manual memory management and environments using garbage collection.
13+
14+So I've some of the code from scratch and taken some from `SCEvents`.
15+
16+## License ##
17+The code is released under the [MIT-license](http://www.opensource.org/licenses/mit-license.php).
\ No newline at end of file
--- /dev/null
+++ b/TestApp/CDEventsTestAppController.h
@@ -0,0 +1,41 @@
1+/**
2+ * CDEvents
3+ *
4+ * Copyright (c) 2010 Aron Cedercrantz
5+ * http://github.com/rastersize/CDEvents/
6+ *
7+ * Permission is hereby granted, free of charge, to any person
8+ * obtaining a copy of this software and associated documentation
9+ * files (the "Software"), to deal in the Software without
10+ * restriction, including without limitation the rights to use,
11+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
12+ * copies of the Software, and to permit persons to whom the
13+ * Software is furnished to do so, subject to the following
14+ * conditions:
15+ *
16+ * The above copyright notice and this permission notice shall be
17+ * included in all copies or substantial portions of the Software.
18+ *
19+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26+ * OTHER DEALINGS IN THE SOFTWARE.
27+ */
28+
29+#import <Foundation/Foundation.h>
30+#import <CDEvents/CDEventsDelegate.h>
31+
32+@class CDEvents;
33+
34+
35+@interface CDEventsTestAppController : NSObject <CDEventsDelegate> {
36+ CDEvents *_events;
37+}
38+
39+- (void)run;
40+
41+@end
--- /dev/null
+++ b/TestApp/CDEventsTestAppController.m
@@ -0,0 +1,65 @@
1+/**
2+ * CDEvents
3+ *
4+ * Copyright (c) 2010 Aron Cedercrantz
5+ * http://github.com/rastersize/CDEvents/
6+ *
7+ * Permission is hereby granted, free of charge, to any person
8+ * obtaining a copy of this software and associated documentation
9+ * files (the "Software"), to deal in the Software without
10+ * restriction, including without limitation the rights to use,
11+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
12+ * copies of the Software, and to permit persons to whom the
13+ * Software is furnished to do so, subject to the following
14+ * conditions:
15+ *
16+ * The above copyright notice and this permission notice shall be
17+ * included in all copies or substantial portions of the Software.
18+ *
19+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26+ * OTHER DEALINGS IN THE SOFTWARE.
27+ */
28+#import "CDEventsTestAppController.h"
29+
30+#import <CDEvents/CDEvent.h>
31+#import <CDEvents/CDEvents.h>
32+
33+
34+@implementation CDEventsTestAppController
35+
36+- (void)run
37+{
38+ NSArray *watchedURLs = [NSArray arrayWithObject:
39+ [NSURL URLWithString:NSHomeDirectory()]];
40+ NSArray *excludeURLs = [NSMutableArray arrayWithObject:
41+ [NSHomeDirectory() stringByAppendingPathComponent:@"Downloads"]];
42+
43+ _events = [[CDEvents alloc] initWithURLs:watchedURLs
44+ delegate:self];
45+ [_events setExcludedURLs:excludeURLs];
46+
47+ NSLog(@"-[CDEventsTestAppController init]:\n%@\n------\n%@",
48+ _events,
49+ [_events streamDescription]);
50+}
51+
52+- (void)dealloc
53+{
54+ [_events setDelegate:nil];
55+ [_events release];
56+
57+ [super dealloc];
58+}
59+
60+- (void)URLWatcher:(CDEvents *)URLWatcher eventOccurred:(CDEvent *)event
61+{
62+ NSLog(@"URLWatcher: %@\nEvent: %@", URLWatcher, event);
63+}
64+
65+@end
--- /dev/null
+++ b/TestApp/main.m
@@ -0,0 +1,51 @@
1+/**
2+ * CDEvents
3+ *
4+ * Copyright (c) 2010 Aron Cedercrantz
5+ * http://github.com/rastersize/CDEvents/
6+ *
7+ * Permission is hereby granted, free of charge, to any person
8+ * obtaining a copy of this software and associated documentation
9+ * files (the "Software"), to deal in the Software without
10+ * restriction, including without limitation the rights to use,
11+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
12+ * copies of the Software, and to permit persons to whom the
13+ * Software is furnished to do so, subject to the following
14+ * conditions:
15+ *
16+ * The above copyright notice and this permission notice shall be
17+ * included in all copies or substantial portions of the Software.
18+ *
19+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26+ * OTHER DEALINGS IN THE SOFTWARE.
27+ */
28+
29+#import "CDEventsTestAppController.h"
30+
31+/**
32+ * Runs forever outputting all changes to the users home directory to the
33+ * standard output (via NSLog()).
34+ *
35+ * The CDEventsTestAppController implements the CDEventsDelegate protocol and
36+ * when it receives any event notificaitons it just echos it to the standard
37+ * output.
38+ */
39+int main(int argc, char *argv[])
40+{
41+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
42+
43+ CDEventsTestAppController *controller = [[[CDEventsTestAppController alloc] init] autorelease];
44+ [controller run];
45+
46+ [[NSRunLoop currentRunLoop] run];
47+
48+ [pool drain];
49+
50+ return 0;
51+}
\ No newline at end of file
--- /dev/null
+++ b/version.plist
@@ -0,0 +1,16 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+<plist version="1.0">
4+<dict>
5+ <key>BuildVersion</key>
6+ <string>2</string>
7+ <key>CFBundleShortVersionString</key>
8+ <string>1.0</string>
9+ <key>CFBundleVersion</key>
10+ <string>1</string>
11+ <key>ProjectName</key>
12+ <string>DevToolsWizardTemplates</string>
13+ <key>SourceVersion</key>
14+ <string>15920000</string>
15+</dict>
16+</plist>