• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

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

Revision4eaf17a300a4cb461aeee7d4039480e9ca07892c (tree)
Time2013-07-03 04:43:35
AuthorAron Cedercrantz <aron@cede...>
CommiterAron Cedercrantz

Log Message

Merge tag '1.2.0'

1.2.0 - Requires ARC and blocks. Does not support GC.

* tag '1.2.0': (32 commits)

Bump copyright years.
Change framework version to 1.2.0.
Update podspec to 1.2.0.
Add compile time check of ARC and blocks.
Update Xcode project.
Fix ARC setting in podspec.
Add podspec by @dwlnetnl (#13).
Remove link to GitHub messages.
Correctly handle path that contains spaces
Made CDEvents class create CDEvent objects with file URLs instead of normal URLs (allows easier comparison with NSURL objects returned by eg. NSFileManager)
Update README.mdown
Fix contributors URL.
Change the authors section in the readme.
Update readme with link to new website.
Ignore "docs" directory.
Update readme to reflect online documentation.
Add license file.
Add script to generate documentation using appledoc.
Update the read me to reflect the new changes.
Update the test app to be able to use blocks API.
...

Change Summary

Incremental Difference

--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,2 @@
1-*.pbxproj binary
21 *.m diff=objc
32 *.mm diff=objc
--- a/.gitignore
+++ b/.gitignore
@@ -27,3 +27,4 @@ build
2727 *~.xib
2828
2929 api
30+docs
--- a/CDEvent.h
+++ b/CDEvent.h
@@ -1,7 +1,7 @@
11 /**
22 * CDEvents
33 *
4- * Copyright (c) 2010 Aron Cedercrantz
4+ * Copyright (c) 2010-2012 Aron Cedercrantz
55 * http://github.com/rastersize/CDEvents/
66 *
77 * Permission is hereby granted, free of charge, to any person
@@ -67,13 +67,7 @@ typedef FSEventStreamEventFlags CDEventFlags;
6767 *
6868 * @since 1.0.0
6969 */
70-@interface CDEvent : NSObject <NSCoding, NSCopying> {
71-@private
72- CDEventIdentifier _identifier;
73- NSDate *_date;
74- NSURL *_URL;
75- CDEventFlags _flags;
76-}
70+@interface CDEvent : NSObject <NSCoding, NSCopying> {}
7771
7872 #pragma mark Properties
7973 /** @name Getting Event Properties */
@@ -95,7 +89,7 @@ typedef FSEventStreamEventFlags CDEventFlags;
9589 *
9690 * @since 1.0.0
9791 */
98-@property (readonly) NSDate *date;
92+@property (unsafe_unretained, readonly) NSDate *date;
9993
10094 /**
10195 * The URL of the item which changed.
@@ -104,7 +98,7 @@ typedef FSEventStreamEventFlags CDEventFlags;
10498 *
10599 * @since 1.0.0
106100 */
107-@property (readonly) NSURL *URL;
101+@property (unsafe_unretained, readonly) NSURL *URL;
108102
109103
110104 /** @name Getting Event Flags */
--- a/CDEvent.m
+++ b/CDEvent.m
@@ -1,7 +1,7 @@
11 /**
22 * CDEvents
33 *
4- * Copyright (c) 2010 Aron Cedercrantz
4+ * Copyright (c) 2010-2012 Aron Cedercrantz
55 * http://github.com/rastersize/CDEvents/
66 *
77 * Permission is hereby granted, free of charge, to any person
@@ -44,22 +44,14 @@
4444 URL:(NSURL *)URL
4545 flags:(CDEventFlags)flags
4646 {
47- return [[[CDEvent alloc] initWithIdentifier:identifier
47+ return [[CDEvent alloc] initWithIdentifier:identifier
4848 date:date
4949 URL:URL
50- flags:flags]
51- autorelease];
50+ flags:flags];
5251 }
5352
5453
5554 #pragma mark Init/dealloc methods
56-- (void)dealloc
57-{
58- [_date release];
59- [_URL release];
60-
61- [super dealloc];
62-}
6355
6456 - (id)initWithIdentifier:(NSUInteger)identifier
6557 date:(NSDate *)date
@@ -69,8 +61,8 @@
6961 if ((self = [super init])) {
7062 _identifier = identifier;
7163 _flags = flags;
72- _date = [date retain];
73- _URL = [URL retain];
64+ _date = date;
65+ _URL = URL;
7466 }
7567
7668 return self;
@@ -101,7 +93,7 @@
10193 - (id)copyWithZone:(NSZone *)zone
10294 {
10395 // We can do this since we are immutable.
104- return [self retain];
96+ return self;
10597 }
10698
10799 #pragma mark Specific flag properties
--- a/CDEvents.h
+++ b/CDEvents.h
@@ -1,7 +1,7 @@
11 /**
22 * CDEvents
33 *
4- * Copyright (c) 2010 Aron Cedercrantz
4+ * Copyright (c) 2010-2012 Aron Cedercrantz
55 * http://github.com/rastersize/CDEvents/
66 *
77 * Permission is hereby granted, free of charge, to any person
@@ -95,6 +95,17 @@ extern const CDEventIdentifier kCDEventsSinceEventNow;
9595
9696
9797 #pragma mark -
98+#pragma mark CDEvents Block Type
99+@class CDEvents;
100+/**
101+ * Type of the block which gets called when an event occurs.
102+ *
103+ * @since head
104+ */
105+typedef void (^CDEventsEventBlock)(CDEvents *watcher, CDEvent *event);
106+
107+
108+#pragma mark -
98109 #pragma mark CDEvents interface
99110 /**
100111 * An Objective-C wrapper for the <code>FSEvents</code> C API.
@@ -105,23 +116,7 @@ extern const CDEventIdentifier kCDEventsSinceEventNow;
105116 *
106117 * @since 1.0.0
107118 */
108-@interface CDEvents : NSObject <NSCopying> {
109-@private
110- __weak id<CDEventsDelegate> _delegate;
111-
112- FSEventStreamRef _eventStream;
113- CFTimeInterval _notificationLatency;
114-
115- CDEventIdentifier _sinceEventIdentifier;
116- NSUInteger _eventStreamCreationFlags;
117-
118- BOOL _ignoreEventsFromSubDirectories;
119-
120- CDEvent *_lastEvent;
121-
122- NSArray *_watchedURLs;
123- NSArray *_excludedURLs;
124-}
119+@interface CDEvents : NSObject <NSCopying> {}
125120
126121 #pragma mark Properties
127122 /** @name Managing the Delegate */
@@ -135,7 +130,17 @@ extern const CDEventIdentifier kCDEventsSinceEventNow;
135130 *
136131 * @since 1.0.0
137132 */
138-@property (assign) __weak id<CDEventsDelegate> delegate;
133+@property (unsafe_unretained) id<CDEventsDelegate> delegate;
134+
135+/** @name Getting Event Block */
136+/**
137+ * The event block.
138+ *
139+ * @return The CDEventsEventBlock block which is executed when an event occurs.
140+ *
141+ * @since head
142+ */
143+@property (readonly) CDEventsEventBlock eventBlock;
139144
140145 /** @name Getting Event Watcher Properties */
141146 /**
@@ -145,7 +150,7 @@ extern const CDEventIdentifier kCDEventsSinceEventNow;
145150 *
146151 * @since 1.0.0
147152 */
148-@property (readonly) CFTimeInterval notificationLatency;
153+@property (readonly) CFTimeInterval notificationLatency;
149154
150155 /**
151156 * The event identifier from which events will be supplied to the delegate.
@@ -154,16 +159,16 @@ extern const CDEventIdentifier kCDEventsSinceEventNow;
154159 *
155160 * @since 1.0.0
156161 */
157-@property (readonly) CDEventIdentifier sinceEventIdentifier;
162+@property (readonly) CDEventIdentifier sinceEventIdentifier;
158163
159164 /**
160- * The last event that occured and thas has been delivered to the delegate.
165+ * The last event that occured and has been delivered to the delegate.
161166 *
162- * @return The last event that occured and thas has been delivered to the delegate.
167+ * @return The last event that occured and has been delivered to the delegate.
163168 *
164169 * @since 1.0.0
165170 */
166-@property (retain, readonly) CDEvent *lastEvent;
171+@property (strong, readonly) CDEvent *lastEvent;
167172
168173 /**
169174 * The URLs that we watch for events.
@@ -172,7 +177,7 @@ extern const CDEventIdentifier kCDEventsSinceEventNow;
172177 *
173178 * @since 1.0.0
174179 */
175-@property (readonly) NSArray *watchedURLs;
180+@property (copy, readonly) NSArray *watchedURLs;
176181
177182
178183 /** @name Configuring the Event watcher */
@@ -184,7 +189,7 @@ extern const CDEventIdentifier kCDEventsSinceEventNow;
184189 *
185190 * @since 1.0.0
186191 */
187-@property (copy) NSArray *excludedURLs;
192+@property (copy) NSArray *excludedURLs;
188193
189194 /**
190195 * Wheter events from sub-directories of the watched URLs should be ignored or not.
@@ -194,7 +199,7 @@ extern const CDEventIdentifier kCDEventsSinceEventNow;
194199 *
195200 * @since 1.0.0
196201 */
197-@property (assign) BOOL ignoreEventsFromSubDirectories;
202+@property (assign) BOOL ignoreEventsFromSubDirectories;
198203
199204
200205 #pragma mark Event identifier class methods
@@ -211,8 +216,8 @@ extern const CDEventIdentifier kCDEventsSinceEventNow;
211216 + (CDEventIdentifier)currentEventIdentifier;
212217
213218
214-#pragma mark Init methods
215-/** @name Creating CDEvents Objects */
219+#pragma mark Creating CDEvents Objects With a Delegate
220+/** @name Creating CDEvents Objects With a Delegate */
216221 /**
217222 * Returns an <code>CDEvents</code> object initialized with the given URLs to watch.
218223 *
@@ -271,8 +276,6 @@ extern const CDEventIdentifier kCDEventsSinceEventNow;
271276 delegate:(id<CDEventsDelegate>)delegate
272277 onRunLoop:(NSRunLoop *)runLoop;
273278
274-
275-
276279 /**
277280 * 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.
278281 *
@@ -311,6 +314,104 @@ ignoreEventsFromSubDirs:(BOOL)ignoreEventsFromSubDirs
311314 excludeURLs:(NSArray *)exludeURLs
312315 streamCreationFlags:(CDEventsEventStreamCreationFlags)streamCreationFlags;
313316
317+#pragma mark Creating CDEvents Objects With a Block
318+/** @name Creating CDEvents Objects With a Block */
319+/**
320+ * Returns an <code>CDEvents</code> object initialized with the given URLs to watch.
321+ *
322+ * @param URLs An array of URLs we want to watch.
323+ * @param block The block which the CDEvents object executes when it recieves an event.
324+ * @return An CDEvents object initialized with the given URLs to watch.
325+ * @throws NSInvalidArgumentException if <em>URLs</em> is empty or points to <code>nil</code>.
326+ * @throws NSInvalidArgumentException if <em>delegate</em>is <code>nil</code>.
327+ * @throws CDEventsEventStreamCreationFailureException if we failed to create a event stream.
328+ *
329+ * @see initWithURLs:delegate:onRunLoop:
330+ * @see initWithURLs:delegate:onRunLoop:sinceEventIdentifier:notificationLantency:ignoreEventsFromSubDirs:excludeURLs:streamCreationFlags:
331+ * @see CDEventsEventBlock
332+ * @see kCDEventsDefaultEventStreamFlags
333+ * @see kCDEventsSinceEventNow
334+ *
335+ * @discussion Calls initWithURLs:block:onRunLoop:sinceEventIdentifier:notificationLantency:ignoreEventsFromSubDirs:excludeURLs:streamCreationFlags:
336+ * with <code>sinceEventIdentifier</code> with the event identifier for "event
337+ * since now", <code>notificationLatency</code> set to 3.0 seconds,
338+ * <code>ignoreEventsFromSubDirectories</code> set to <code>NO</code>,
339+ * <code>excludedURLs</code> to <code>nil</code>, the event stream creation
340+ * flags will be set to <code>kCDEventsDefaultEventStreamFlags</code> and
341+ * schedueled on the current run loop.
342+ *
343+ * @since head
344+ */
345+- (id)initWithURLs:(NSArray *)URLs block:(CDEventsEventBlock)block;
346+
347+/**
348+ * Returns an <code>CDEvents</code> object initialized with the given URLs to watch and schedules the watcher on the given run loop.
349+ *
350+ * @param URLs An array of URLs we want to watch.
351+ * @param block The block which the CDEvents object executes when it recieves an event.
352+ * @param runLoop The run loop which the which the watcher should be schedueled on.
353+ * @return An CDEvents object initialized with the given URLs to watch.
354+ * @throws NSInvalidArgumentException if <em>URLs</em> is empty or points to <code>nil</code>.
355+ * @throws NSInvalidArgumentException if <em>delegate</em>is <code>nil</code>.
356+ * @throws CDEventsEventStreamCreationFailureException if we failed to create a event stream.
357+ *
358+ * @see initWithURLs:delegate:
359+ * @see initWithURLs:delegate:onRunLoop:sinceEventIdentifier:notificationLantency:ignoreEventsFromSubDirs:excludeURLs:streamCreationFlags:
360+ * @see CDEventsEventBlock
361+ * @see kCDEventsDefaultEventStreamFlags
362+ * @see kCDEventsSinceEventNow
363+ *
364+ * @discussion Calls initWithURLs:delegate:onRunLoop:sinceEventIdentifier:notificationLantency:ignoreEventsFromSubDirs:excludeURLs:streamCreationFlags:
365+ * with <code>sinceEventIdentifier</code> with the event identifier for "event
366+ * since now", <code>notificationLatency</code> set to 3.0 seconds,
367+ * <code>ignoreEventsFromSubDirectories</code> set to <code>NO</code>,
368+ * <code>excludedURLs</code> to <code>nil</code> and the event stream creation
369+ * flags will be set to <code>kCDEventsDefaultEventStreamFlags</code>.
370+ *
371+ * @since head
372+ */
373+- (id)initWithURLs:(NSArray *)URLs
374+ block:(CDEventsEventBlock)block
375+ onRunLoop:(NSRunLoop *)runLoop;
376+
377+/**
378+ * 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.
379+ *
380+ * @param URLs An array of URLs (<code>NSURL</code>) we want to watch.
381+ * @param block The block which the CDEvents object executes when it recieves an event.
382+ * @param runLoop The run loop which the which the watcher should be schedueled on.
383+ * @param sinceEventIdentifier Events that have happened after the given event identifier will be supplied.
384+ * @param notificationLatency The (approximate) time intervall between notifications sent to the delegate.
385+ * @param ignoreEventsFromSubDirs Wheter events from sub-directories of the watched URLs should be ignored or not.
386+ * @param exludeURLs An array of URLs that we should ignore events from. Pass <code>nil</code> if none should be excluded.
387+ * @param streamCreationFlags The event stream creation flags.
388+ * @return An CDEvents 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.
389+ * @throws NSInvalidArgumentException if the parameter URLs is empty or points to <code>nil</code>.
390+ * @throws NSInvalidArgumentException if <em>delegate</em>is <code>nil</code>.
391+ * @throws CDEventsEventStreamCreationFailureException if we failed to create a event stream.
392+ *
393+ * @see initWithURLs:delegate:
394+ * @see initWithURLs:delegate:onRunLoop:
395+ * @see ignoreEventsFromSubDirectories
396+ * @see excludedURLs
397+ * @see CDEventsEventBlock
398+ * @see FSEventStreamCreateFlags
399+ *
400+ * @discussion To ask for events "since now" pass the return value of
401+ * currentEventIdentifier as the parameter <code>sinceEventIdentifier</code>.
402+ * CDEventStreamCreationFailureException should be extremely rare.
403+ *
404+ * @since head
405+ */
406+- (id)initWithURLs:(NSArray *)URLs
407+ block:(CDEventsEventBlock)block
408+ onRunLoop:(NSRunLoop *)runLoop
409+sinceEventIdentifier:(CDEventIdentifier)sinceEventIdentifier
410+notificationLantency:(CFTimeInterval)notificationLatency
411+ignoreEventsFromSubDirs:(BOOL)ignoreEventsFromSubDirs
412+ excludeURLs:(NSArray *)exludeURLs
413+streamCreationFlags:(CDEventsEventStreamCreationFlags)streamCreationFlags;
414+
314415 #pragma mark Flush methods
315416 /** @name Flushing Events */
316417 /**
--- a/CDEvents.m
+++ b/CDEvents.m
@@ -1,15 +1,48 @@
1-//
2-// CDEvents.m
3-// CDEvents
4-//
5-// Created by Aron Cedercrantz on 03/04/10.
6-// Copyright 2010 __MyCompanyName__. All rights reserved.
7-//
1+/**
2+ * CDEvents
3+ *
4+ * Copyright (c) 2010-2012 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+ */
828
929 #import "CDEvents.h"
1030
1131 #import "CDEventsDelegate.h"
1232
33+#ifndef __has_feature
34+ #define __has_feature(x) 0
35+#endif
36+
37+#if !__has_feature(objc_arc)
38+ #error CDEvents must be built with ARC.
39+#endif
40+
41+#if !__has_feature(blocks)
42+ #error CDEvents must be built with support for blocks.
43+#endif
44+
45+
1346 #pragma mark CDEvents custom exceptions
1447 NSString *const CDEventsEventStreamCreationFailureException = @"CDEventsEventStreamCreationFailureException";
1548
@@ -25,9 +58,17 @@ const CDEventIdentifier kCDEventsSinceEventNow = kFSEventStreamEventIdSinceNow;
2558 #pragma mark -
2659 #pragma mark Private API
2760 // Private API
28-@interface CDEvents ()
61+@interface CDEvents () {
62+@private
63+ CDEventsEventBlock _eventBlock;
64+
65+ FSEventStreamRef _eventStream;
66+ NSUInteger _eventStreamCreationFlags;
67+}
2968
30-@property (retain, readwrite) CDEvent *lastEvent;
69+// Redefine the properties that should be writeable.
70+@property (strong, readwrite) CDEvent *lastEvent;
71+@property (copy, readwrite) NSArray *watchedURLs;
3172
3273 // The FSEvents callback function
3374 static void CDEventsCallback(
@@ -73,12 +114,6 @@ static void CDEventsCallback(
73114 [self disposeEventStream];
74115
75116 _delegate = nil;
76-
77- [_lastEvent release];
78- [_watchedURLs release];
79- [_excludedURLs release];
80-
81- [super dealloc];
82117 }
83118
84119 - (void)finalize
@@ -113,22 +148,73 @@ static void CDEventsCallback(
113148
114149 - (id)initWithURLs:(NSArray *)URLs
115150 delegate:(id<CDEventsDelegate>)delegate
116- onRunLoop:(NSRunLoop *)runLoop
151+ onRunLoop:(NSRunLoop *)runLoop
117152 sinceEventIdentifier:(CDEventIdentifier)sinceEventIdentifier
118153 notificationLantency:(CFTimeInterval)notificationLatency
119154 ignoreEventsFromSubDirs:(BOOL)ignoreEventsFromSubDirs
120- excludeURLs:(NSArray *)exludeURLs
121- streamCreationFlags:(CDEventsEventStreamCreationFlags)streamCreationFlags
155+ excludeURLs:(NSArray *)exludeURLs
156+streamCreationFlags:(CDEventsEventStreamCreationFlags)streamCreationFlags
122157 {
123- if (delegate == nil || URLs == nil || [URLs count] == 0) {
158+ if (delegate == nil) {
159+ [NSException raise:NSInvalidArgumentException
160+ format:@"Invalid arguments passed to CDEvents init-method."];
161+ }
162+
163+ _delegate = delegate;
164+
165+ return [self initWithURLs:URLs
166+ block:^(CDEvents *watcher, CDEvent *event){
167+ if ([(id)[watcher delegate] conformsToProtocol:@protocol(CDEventsDelegate)]) {
168+ [[watcher delegate] URLWatcher:watcher eventOccurred:event];
169+ }
170+ }
171+ onRunLoop:runLoop
172+ sinceEventIdentifier:sinceEventIdentifier
173+ notificationLantency:notificationLatency
174+ ignoreEventsFromSubDirs:ignoreEventsFromSubDirs
175+ excludeURLs:exludeURLs
176+ streamCreationFlags:streamCreationFlags];
177+}
178+
179+
180+#pragma mark Creating CDEvents Objects With a Block
181+- (id)initWithURLs:(NSArray *)URLs block:(CDEventsEventBlock)block
182+{
183+ return [self initWithURLs:URLs block:block onRunLoop:[NSRunLoop currentRunLoop]];
184+}
185+
186+- (id)initWithURLs:(NSArray *)URLs
187+ block:(CDEventsEventBlock)block
188+ onRunLoop:(NSRunLoop *)runLoop
189+{
190+ return [self initWithURLs:URLs
191+ block:block
192+ onRunLoop:runLoop
193+ sinceEventIdentifier:kCDEventsSinceEventNow
194+ notificationLantency:CD_EVENTS_DEFAULT_NOTIFICATION_LATENCY
195+ ignoreEventsFromSubDirs:CD_EVENTS_DEFAULT_IGNORE_EVENT_FROM_SUB_DIRS
196+ excludeURLs:nil
197+ streamCreationFlags:kCDEventsDefaultEventStreamFlags];
198+}
199+
200+- (id)initWithURLs:(NSArray *)URLs
201+ block:(CDEventsEventBlock)block
202+ onRunLoop:(NSRunLoop *)runLoop
203+sinceEventIdentifier:(CDEventIdentifier)sinceEventIdentifier
204+notificationLantency:(CFTimeInterval)notificationLatency
205+ignoreEventsFromSubDirs:(BOOL)ignoreEventsFromSubDirs
206+ excludeURLs:(NSArray *)exludeURLs
207+streamCreationFlags:(CDEventsEventStreamCreationFlags)streamCreationFlags
208+{
209+ if (block == NULL || URLs == nil || [URLs count] == 0) {
124210 [NSException raise:NSInvalidArgumentException
125211 format:@"Invalid arguments passed to CDEvents init-method."];
126212 }
127213
128214 if ((self = [super init])) {
129215 _watchedURLs = [URLs copy];
130- [self setExcludedURLs:exludeURLs];
131- [self setDelegate:delegate];
216+ _excludedURLs = [exludeURLs copy];
217+ _eventBlock = block;
132218
133219 _sinceEventIdentifier = sinceEventIdentifier;
134220 _eventStreamCreationFlags = streamCreationFlags;
@@ -157,7 +243,7 @@ ignoreEventsFromSubDirs:(BOOL)ignoreEventsFromSubDirs
157243 - (id)copyWithZone:(NSZone *)zone
158244 {
159245 CDEvents *copy = [[CDEvents alloc] initWithURLs:[self watchedURLs]
160- delegate:[self delegate]
246+ block:[self eventBlock]
161247 onRunLoop:[NSRunLoop currentRunLoop]
162248 sinceEventIdentifier:[self sinceEventIdentifier]
163249 notificationLantency:[self notificationLatency]
@@ -168,6 +254,12 @@ ignoreEventsFromSubDirs:(BOOL)ignoreEventsFromSubDirs
168254 return copy;
169255 }
170256
257+#pragma mark Block
258+- (CDEventsEventBlock)eventBlock
259+{
260+ return _eventBlock;
261+}
262+
171263
172264 #pragma mark Flush methods
173265 - (void)flushSynchronously
@@ -193,10 +285,10 @@ ignoreEventsFromSubDirs:(BOOL)ignoreEventsFromSubDirs
193285 - (NSString *)streamDescription
194286 {
195287 CFStringRef streamDescriptionCF = FSEventStreamCopyDescription(_eventStream);
196- NSString *returnString = [[NSString alloc] initWithString:(NSString *)streamDescriptionCF];
288+ NSString *returnString = [[NSString alloc] initWithString:(__bridge NSString *)streamDescriptionCF];
197289 CFRelease(streamDescriptionCF);
198290
199- return [returnString autorelease];
291+ return returnString;
200292 }
201293
202294
@@ -205,7 +297,7 @@ ignoreEventsFromSubDirs:(BOOL)ignoreEventsFromSubDirs
205297 {
206298 FSEventStreamContext callbackCtx;
207299 callbackCtx.version = 0;
208- callbackCtx.info = (void *)self;
300+ callbackCtx.info = (__bridge void *)self;
209301 callbackCtx.retain = NULL;
210302 callbackCtx.release = NULL;
211303 callbackCtx.copyDescription = NULL;
@@ -218,7 +310,7 @@ ignoreEventsFromSubDirs:(BOOL)ignoreEventsFromSubDirs
218310 _eventStream = FSEventStreamCreate(kCFAllocatorDefault,
219311 &CDEventsCallback,
220312 &callbackCtx,
221- (CFArrayRef)watchedPaths,
313+ (__bridge CFArrayRef)watchedPaths,
222314 (FSEventStreamEventId)[self sinceEventIdentifier],
223315 [self notificationLatency],
224316 _eventStreamCreationFlags);
@@ -240,39 +332,40 @@ static void CDEventsCallback(
240332 ConstFSEventStreamRef streamRef,
241333 void *callbackCtxInfo,
242334 size_t numEvents,
243- void *eventPaths,
335+ void *eventPaths, // CFArrayRef
244336 const FSEventStreamEventFlags eventFlags[],
245337 const FSEventStreamEventId eventIds[])
246338 {
247- CDEvents *watcher = (CDEvents *)callbackCtxInfo;
248-
339+ CDEvents *watcher = (__bridge CDEvents *)callbackCtxInfo;
340+ NSArray *eventPathsArray = (__bridge NSArray *)eventPaths;
249341 NSArray *watchedURLs = [watcher watchedURLs];
250342 NSArray *excludedURLs = [watcher excludedURLs];
251- NSArray *eventPathsArray = (NSArray *)eventPaths;
252- BOOL shouldIgnore = NO;
253343 CDEvent *lastEvent = nil;
254-
344+
255345 for (NSUInteger i = 0; i < numEvents; ++i) {
256- shouldIgnore = NO;
346+ BOOL shouldIgnore = NO;
347+ FSEventStreamEventFlags flags = eventFlags[i];
348+ FSEventStreamEventId identifier = eventIds[i];
257349
258- NSString *eventPath = [[eventPathsArray objectAtIndex:i]
259- stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
260- NSURL *eventURL = [NSURL URLWithString:eventPath];
261350 // We do this hackery to ensure that the eventPath string doesn't
262351 // contain any trailing slash.
263- eventPath = [eventURL path];
352+ NSURL *eventURL = [NSURL fileURLWithPath:[[eventPathsArray objectAtIndex:i] stringByStandardizingPath]];
353+ NSString *eventPath = [eventURL path];
264354
355+ // Ignore all events except for the URLs we are explicitly watching.
265356 if ([watcher ignoreEventsFromSubDirectories]) {
266357 shouldIgnore = YES;
267- for (NSURL *URL in watchedURLs) {
268- if ([[URL path] isEqualToString:eventPath]) {
358+ for (NSURL *url in watchedURLs) {
359+ if ([[url path] isEqualToString:eventPath]) {
269360 shouldIgnore = NO;
270361 break;
271362 }
272363 }
364+ // Ignore all explicitly excludeded URLs (not required to check if we
365+ // ignore all events from sub-directories).
273366 } else if (excludedURLs != nil) {
274- for (NSURL *URL in excludedURLs) {
275- if ([eventPath hasPrefix:[URL path]]) {
367+ for (NSURL *url in excludedURLs) {
368+ if ([eventPath hasPrefix:[url path]]) {
276369 shouldIgnore = YES;
277370 break;
278371 }
@@ -280,30 +373,16 @@ static void CDEventsCallback(
280373 }
281374
282375 if (!shouldIgnore) {
283- CDEvent *event = [[CDEvent alloc] initWithIdentifier:eventIds[i]
284- date:[NSDate date]
285- URL:eventURL
286- flags:eventFlags[i]];
287- // Dispose of old lastEvent and retain the currently last
288- [lastEvent release];
289- lastEvent = [event retain];
290-
291- if ([(id)[watcher delegate] conformsToProtocol:@protocol(CDEventsDelegate)]) {
292- [[watcher delegate] URLWatcher:watcher eventOccurred:event];
293- }
294-
295- // Last event?
296- if (i == (numEvents - 1)) {
297- [watcher setLastEvent:event];
298- }
376+ CDEvent *event = [[CDEvent alloc] initWithIdentifier:identifier date:[NSDate date] URL:eventURL flags:flags];
377+ lastEvent = event;
299378
300- [event release];
379+ CDEventsEventBlock eventBlock = [watcher eventBlock];
380+ eventBlock(watcher, event);
301381 }
302382 }
303383
304384 if (lastEvent) {
305385 [watcher setLastEvent:lastEvent];
306- [lastEvent release];
307386 }
308387 }
309388
--- /dev/null
+++ b/CDEvents.podspec
@@ -0,0 +1,13 @@
1+Pod::Spec.new do |s|
2+ s.name = "CDEvents"
3+ s.version = "1.2.0"
4+ s.summary = "An Objective-C wrapper for Mac OS X’s FSEvents C API."
5+ s.homepage = "http://rastersize.github.com/CDEvents"
6+ s.license = { :type => 'MIT', :file => 'LICENSE' }
7+ s.author = { "Aron Cedercrantz" => "aron@cedercrantz.se" }
8+ s.source = { :git => "https://github.com/rastersize/CDEvents.git", :tag => "1.2.0" }
9+ s.platform = :osx, '10.6'
10+ s.source_files = '*.{h,m}'
11+ s.framework = 'CoreServices'
12+ s.requires_arc = true
13+end
\ No newline at end of file
--- a/CDEvents.xcodeproj/project.pbxproj
+++ b/CDEvents.xcodeproj/project.pbxproj
@@ -242,7 +242,8 @@
242242 0867D690FE84028FC02AAC07 /* Project object */ = {
243243 isa = PBXProject;
244244 attributes = {
245- LastUpgradeCheck = 0420;
245+ LastUpgradeCheck = 0460;
246+ ORGANIZATIONNAME = "Aron Cedercrantz";
246247 };
247248 buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "CDEvents" */;
248249 compatibilityVersion = "Xcode 3.2";
@@ -328,17 +329,19 @@
328329 isa = XCBuildConfiguration;
329330 buildSettings = {
330331 ALWAYS_SEARCH_USER_PATHS = NO;
332+ CLANG_ENABLE_OBJC_ARC = YES;
333+ COMBINE_HIDPI_IMAGES = YES;
331334 COPY_PHASE_STRIP = NO;
332335 DYLIB_COMPATIBILITY_VERSION = 1;
333336 DYLIB_CURRENT_VERSION = 1;
334337 FRAMEWORK_VERSION = A;
335338 GCC_DYNAMIC_NO_PIC = NO;
336- GCC_ENABLE_OBJC_GC = supported;
337- GCC_MODEL_TUNING = G5;
339+ GCC_ENABLE_OBJC_GC = unsupported;
340+ GCC_MODEL_TUNING = "";
338341 GCC_OPTIMIZATION_LEVEL = 0;
339342 GCC_PRECOMPILE_PREFIX_HEADER = YES;
340343 GCC_PREFIX_HEADER = CDEvents_Prefix.pch;
341- GCC_PREPROCESSOR_DEFINITIONS = NS_BUILD_32_LIKE_64;
344+ GCC_PREPROCESSOR_DEFINITIONS = "";
342345 INFOPLIST_FILE = Info.plist;
343346 INSTALL_PATH = "@loader_path/../Frameworks";
344347 PRODUCT_NAME = CDEvents;
@@ -350,15 +353,17 @@
350353 isa = XCBuildConfiguration;
351354 buildSettings = {
352355 ALWAYS_SEARCH_USER_PATHS = NO;
356+ CLANG_ENABLE_OBJC_ARC = YES;
357+ COMBINE_HIDPI_IMAGES = YES;
353358 DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
354359 DYLIB_COMPATIBILITY_VERSION = 1;
355360 DYLIB_CURRENT_VERSION = 1;
356361 FRAMEWORK_VERSION = A;
357- GCC_ENABLE_OBJC_GC = supported;
358- GCC_MODEL_TUNING = G5;
362+ GCC_ENABLE_OBJC_GC = unsupported;
363+ GCC_MODEL_TUNING = "";
359364 GCC_PRECOMPILE_PREFIX_HEADER = YES;
360365 GCC_PREFIX_HEADER = CDEvents_Prefix.pch;
361- GCC_PREPROCESSOR_DEFINITIONS = NS_BUILD_32_LIKE_64;
366+ GCC_PREPROCESSOR_DEFINITIONS = "";
362367 INFOPLIST_FILE = Info.plist;
363368 INSTALL_PATH = "@loader_path/../Frameworks";
364369 PRODUCT_NAME = CDEvents;
@@ -369,16 +374,19 @@
369374 1DEB91B208733DA50010E9CD /* Debug */ = {
370375 isa = XCBuildConfiguration;
371376 buildSettings = {
372- ARCHS = (
373- x86_64,
374- i386,
375- );
377+ ARCHS = "$(ARCHS_STANDARD_64_BIT)";
378+ CLANG_WARN_CONSTANT_CONVERSION = YES;
379+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
380+ CLANG_WARN_INT_CONVERSION = YES;
381+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
376382 GCC_C_LANGUAGE_STANDARD = gnu99;
383+ GCC_ENABLE_SSE3_EXTENSIONS = YES;
377384 GCC_OPTIMIZATION_LEVEL = 0;
378385 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
379386 GCC_WARN_ABOUT_RETURN_TYPE = YES;
387+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
380388 GCC_WARN_UNUSED_VARIABLE = YES;
381- MACOSX_DEPLOYMENT_TARGET = 10.5;
389+ MACOSX_DEPLOYMENT_TARGET = 10.6;
382390 ONLY_ACTIVE_ARCH = YES;
383391 RUN_CLANG_STATIC_ANALYZER = YES;
384392 SDKROOT = macosx;
@@ -388,15 +396,18 @@
388396 1DEB91B308733DA50010E9CD /* Release */ = {
389397 isa = XCBuildConfiguration;
390398 buildSettings = {
391- ARCHS = (
392- x86_64,
393- i386,
394- );
399+ ARCHS = "$(ARCHS_STANDARD_64_BIT)";
400+ CLANG_WARN_CONSTANT_CONVERSION = YES;
401+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
402+ CLANG_WARN_INT_CONVERSION = YES;
403+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
395404 GCC_C_LANGUAGE_STANDARD = gnu99;
405+ GCC_ENABLE_SSE3_EXTENSIONS = YES;
396406 GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
397407 GCC_WARN_ABOUT_RETURN_TYPE = YES;
408+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
398409 GCC_WARN_UNUSED_VARIABLE = YES;
399- MACOSX_DEPLOYMENT_TARGET = 10.5;
410+ MACOSX_DEPLOYMENT_TARGET = 10.6;
400411 RUN_CLANG_STATIC_ANALYZER = YES;
401412 SDKROOT = macosx;
402413 };
@@ -406,14 +417,15 @@
406417 isa = XCBuildConfiguration;
407418 buildSettings = {
408419 ALWAYS_SEARCH_USER_PATHS = NO;
420+ COMBINE_HIDPI_IMAGES = YES;
409421 COPY_PHASE_STRIP = NO;
410422 GCC_DYNAMIC_NO_PIC = NO;
411423 GCC_ENABLE_OBJC_GC = unsupported;
412- GCC_MODEL_TUNING = G5;
424+ GCC_MODEL_TUNING = "";
413425 GCC_OPTIMIZATION_LEVEL = 0;
414426 GCC_PRECOMPILE_PREFIX_HEADER = YES;
415427 GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
416- GCC_PREPROCESSOR_DEFINITIONS = NS_BUILD_32_LIKE_64;
428+ GCC_PREPROCESSOR_DEFINITIONS = "";
417429 INFOPLIST_FILE = "CDEventsTestApp-Info.plist";
418430 INSTALL_PATH = "$(HOME)/Applications";
419431 LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
@@ -424,6 +436,7 @@
424436 AppKit,
425437 );
426438 PRODUCT_NAME = CDEventsTestApp;
439+ ZERO_LINK = NO;
427440 };
428441 name = Debug;
429442 };
@@ -431,13 +444,14 @@
431444 isa = XCBuildConfiguration;
432445 buildSettings = {
433446 ALWAYS_SEARCH_USER_PATHS = NO;
447+ COMBINE_HIDPI_IMAGES = YES;
434448 COPY_PHASE_STRIP = YES;
435449 DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
436450 GCC_ENABLE_OBJC_GC = unsupported;
437- GCC_MODEL_TUNING = G5;
451+ GCC_MODEL_TUNING = "";
438452 GCC_PRECOMPILE_PREFIX_HEADER = YES;
439453 GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
440- GCC_PREPROCESSOR_DEFINITIONS = NS_BUILD_32_LIKE_64;
454+ GCC_PREPROCESSOR_DEFINITIONS = "";
441455 INFOPLIST_FILE = "CDEventsTestApp-Info.plist";
442456 INSTALL_PATH = "$(HOME)/Applications";
443457 LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
--- a/CDEventsDelegate.h
+++ b/CDEventsDelegate.h
@@ -1,7 +1,7 @@
11 /**
2- * SCEvents
2+ * CDEvents
33 *
4- * Copyright (c) 2010 Aron Cedercrantz
4+ * Copyright (c) 2010-2012 Aron Cedercrantz
55 * http://github.com/rastersize/CDEvents/
66 *
77 * Permission is hereby granted, free of charge, to any person
--- a/Info.plist
+++ b/Info.plist
@@ -17,11 +17,11 @@
1717 <key>CFBundlePackageType</key>
1818 <string>FMWK</string>
1919 <key>CFBundleShortVersionString</key>
20- <string>1.1.2</string>
20+ <string>1.2.0</string>
2121 <key>CFBundleSignature</key>
2222 <string>????</string>
2323 <key>CFBundleVersion</key>
24- <string>1.1.2</string>
24+ <string>1.2.0</string>
2525 <key>NSPrincipalClass</key>
2626 <string></string>
2727 </dict>
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,7 @@
1+Copyright (c) 2010, 2011 Aron Cedercrantz
2+
3+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4+
5+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6+
7+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- a/README.mdown
+++ b/README.mdown
@@ -1,26 +1,92 @@
1-# CDEvents ![Project status](http://stillmaintained.com/rastersize/CDEvents.png) #
1+# CDEvents
2+***Note:*** The `develop` branch **requires Mac OS X 10.6 or newer** as the framework relies on [ARC](http://clang.llvm.org/docs/AutomaticReferenceCounting.html "Automatic Reference Counting Technical Specification") and [blocks](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html "Blocks Programming Topics").
23
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/).
4+Website: http://rastersize.github.com/CDEvents
55
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.
6+## What is this?
7+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) with support for blocks. Furthermore, all the classes are immutable and it should be thread-safe.
88
9-## What differentiates CDEvents from SCEvents then? ##
10-Not all that much but a few things differentiate the two. The (event data wrapper) class `CDEvent` is immutable in contrast to `SCEvent` which is mutable. The next difference, which were the initial reason why I decided to rewrite `SCEvents` is that the class `SCEvents`' is a singleton class, where's `CDEvents` is a "normal" class. I couldn't find a good reason as to why `SCEvents` had been designed that way and for my project a "normal" non-singleton class would be and is better.
119
12-Another difference between `CDEvents` and `SCEvents` is that `CDEvents` is available for both manual memory management and environments using garbage collection.
10+## Requirements
11+Requires Mac OS X 10.6 (Snow Leopard) and an Intel 64-bit CPU. The requirements stems from that automatic reference counting (ARC) is supported from 10.6 and up as long as the modern (i.e. 64-bit) Objective-C runtime is used since ARC requires the non-fragile ABI. Although the built product works on 10.6 and up it must be built on a machine running 10.7 (Lion) using Xcode 4.2 and the 10.7 SDK as the 10.6 SDK does not include ARC. The built product support both manual memory management and automatic reference counting.
1312
14-So I've written some of the code from scratch and "borrowed" some from `SCEvents`.
13+If you need to support older versions of OS X or garbage collection please see the branch `support/1.1`. All _1.1.x_ version will support garbage collection and OS X 10.5.
1514
16-## API documentation ##
17-You can generate API documentation with the help of [Doxygen](http://www.stack.nl/~dimitri/doxygen/). In Doxygen open the file `api.doxygen`, click the `Run` tab and then the `Run doxygen` button. When it's done you should have a directory (ignored by git) in the root of the project named `api` with a sub-directory `html` in which you will find `index.html` double-click and enjoy.
1815
19-## Authors ##
16+## Usage
17+You can use either the block based version (recommended) or the delegate based. Using both systems at the same time is not supported.
18+
19+### Block based (recommended)
20+1. Add CDEvents to your project,
21+ * either by compiling the project and dragging the `CDEvents.framework` into your project or
22+ * by dragging the entire CDEvents project into your project as a sub-project.
23+2. Import the `CDEvents.h` header where you need it.
24+3. Set up your `CDEvents` instance and give it a block to execute when a event occurs.
25+
26+Easy example code:
27+
28+ self.events = [[CDEvents alloc]] initWithURLs:<NSArray of URLs to watch>
29+ block:^(CDEvents *watcher, CDEvent *event) {
30+ <Your code here>
31+ }];
32+
33+Or use all the all-options initiator:
34+
35+ self.events = [[CDEvents alloc] initWithURLs:<NSArray of URLs to watch>
36+ block:^(CDEvents *watcher, CDEvent *event) {
37+ <Your code here>
38+ }
39+ onRunLoop:[NSRunLoop currentRunLoop]
40+ sinceEventIdentifier:kCDEventsSinceEventNow
41+ notificationLantency:CD_EVENTS_DEFAULT_NOTIFICATION_LATENCY
42+ ignoreEventsFromSubDirs:CD_EVENTS_DEFAULT_IGNORE_EVENT_FROM_SUB_DIRS
43+ excludeURLs:<NSArray of URLs to exlude>
44+ streamCreationFlags:kCDEventsDefaultEventStreamFlags];
45+
46+See the test app (`TestApp`) for an example on how to use the framework.
47+
48+### Delegate based
49+***This is the same behavior as pre ARC and blocks.***
50+
51+1. Add CDEvents to your project,
52+ * either by compiling the project and dragging the `CDEvents.framework` into your project or
53+ * by dragging the entire CDEvents project into your project as a sub-project.
54+2. Import the `CDEvents.h` header where you need it.
55+3. Import the `CDEventsDelegate.h` header where you need it (i.e. in the file which declares your delegate).
56+4. Implement the delegate (`-URLWatcher:eventOccurred:`) and create your `CDEvents` instance.
57+5. Zero out the delegate when you no longer need it.
58+
59+Example code:
60+
61+ self.events = [[CDEvents alloc] initWithURLs:<NSArray of URLs to watch>
62+ delegate:<Your delegate>
63+ onRunLoop:[NSRunLoop currentRunLoop]
64+ sinceEventIdentifier:kCDEventsSinceEventNow
65+ notificationLantency:CD_EVENTS_DEFAULT_NOTIFICATION_LATENCY
66+ ignoreEventsFromSubDirs:CD_EVENTS_DEFAULT_IGNORE_EVENT_FROM_SUB_DIRS
67+ excludeURLs:<NSArray of URLs to exlude>
68+ streamCreationFlags:kCDEventsDefaultEventStreamFlags];
69+
70+See the test app (`TestApp`) for an example on how to use the framework.
71+
72+**Important:** Since Mac OS X 10.6 is set as the deployment target automatic zeroing of weak references is not available. Thus you must set the `delegate` of `CDEvents` to `nil` when you no longer want to receive events. That is, at least in your `-dealloc` method. This is also required when using 10.7 and up! (`delegate` is an `unsafe_unretained` property.)
73+
74+For more details please refer to the documentation in the header files and the section "API documentation" below.
75+
76+
77+## API documentation
78+Read the latest [API documentation](http://rastersize.github.com/CDEvents/docs/api/head) or [browse for each version](http://rastersize.github.com/CDEvents/docs/api) of CDEvents. Alternatively you can generate it yourself, please see below.
79+
80+### appledoc
81+Run the script `api.appledoc.sh` from the root of the project. The script takes one optional argument, the version of the project as a string. If the version string is empty "HEAD" will be used instead.
82+
83+### Doxygen
84+You can generate API documentation with the help of [Doxygen](http://www.stack.nl/~dimitri/doxygen/). In Doxygen open the file `api.doxygen`, click the `Run` tab and then the `Run doxygen` button. When it's done you should have a directory (ignored by git) in the root of the project named `api` with a sub-directory `html` in which you will find `index.html` double-click and enjoy.
2085
21-* Aron Cedercrantz
86+## Contributors
87+See GitHubs [contributors to rastersize/CDEvents](https://github.com/rastersize/CDEvents/contributors) statistics page.
2288
23-## License ##
89+## License
2490 The code is released under the [MIT-license](http://www.opensource.org/licenses/mit-license.php).
2591
26-If you want, even though you really don't have to, I would love hearing what you use CDEvents for! Send me an email (first name @ last name dot se) or a [message via GitHub](http://github.com/inbox/new/rastersize).
92+If you want, even though you really don't have to, I would love to hear what you use CDEvents for! Send me an email (first name (i.e. aron) @ last name (i.e. cedercrantz) dot se).
--- a/TestApp/CDEventsTestAppController.m
+++ b/TestApp/CDEventsTestAppController.m
@@ -31,6 +31,9 @@
3131 #import <CDEvents/CDEvents.h>
3232
3333
34+#define CD_EVENTS_TEST_APP_USE_BLOCKS_API 1
35+
36+
3437 bool systemVersionIsAtLeast(SInt32 major, SInt32 minor)
3538 {
3639 static SInt32 versionMajor = 0, versionMinor = 0;
@@ -69,6 +72,16 @@ bool systemVersionIsAtLeast(SInt32 major, SInt32 minor)
6972 creationFlags |= kFSEventStreamCreateFlagFileEvents;
7073 }
7174
75+#if CD_EVENTS_TEST_APP_USE_BLOCKS_API
76+ _events = [[CDEvents alloc] initWithURLs:watchedURLs
77+ block:^(CDEvents *watcher, CDEvent *event){ NSLog(@"[Block] URLWatcher: %@\nEvent: %@", watcher, event); }
78+ onRunLoop:[NSRunLoop currentRunLoop]
79+ sinceEventIdentifier:kCDEventsSinceEventNow
80+ notificationLantency:CD_EVENTS_DEFAULT_NOTIFICATION_LATENCY
81+ ignoreEventsFromSubDirs:CD_EVENTS_DEFAULT_IGNORE_EVENT_FROM_SUB_DIRS
82+ excludeURLs:excludeURLs
83+ streamCreationFlags:creationFlags];
84+#else
7285 _events = [[CDEvents alloc] initWithURLs:watchedURLs
7386 delegate:self
7487 onRunLoop:[NSRunLoop currentRunLoop]
@@ -78,6 +91,7 @@ bool systemVersionIsAtLeast(SInt32 major, SInt32 minor)
7891 excludeURLs:excludeURLs
7992 streamCreationFlags:creationFlags];
8093 //[_events setIgnoreEventsFromSubDirectories:YES];
94+#endif
8195
8296 NSLog(@"-[CDEventsTestAppController run]:\n%@\n------\n%@",
8397 _events,
@@ -92,9 +106,9 @@ bool systemVersionIsAtLeast(SInt32 major, SInt32 minor)
92106 [super dealloc];
93107 }
94108
95-- (void)URLWatcher:(CDEvents *)URLWatcher eventOccurred:(CDEvent *)event
109+- (void)URLWatcher:(CDEvents *)urlWatcher eventOccurred:(CDEvent *)event
96110 {
97- NSLog(@"URLWatcher: %@\nEvent: %@", URLWatcher, event);
111+ NSLog(@"[Delegate] URLWatcher: %@\nEvent: %@", urlWatcher, event);
98112 }
99113
100114 @end
--- /dev/null
+++ b/api.appledoc.sh
@@ -0,0 +1,45 @@
1+#!/bin/sh
2+
3+##
4+# USAGE
5+# ./api.appledoc.sh [version-string]
6+#
7+# Execute it from the root of the CDEvents project.
8+
9+
10+PROJECT_VERSION="HEAD"
11+if [ "$#" -gt "0" ]
12+then
13+ PROJECT_VERSION=$1
14+fi
15+
16+API_DOCS_DIR="./api/appledoc"
17+#HEADER_FILES=`find . -name '*.h'`
18+HEADER_FILES=`ls *.h`
19+
20+
21+echo "API documentation generator for CDEvents v1"
22+echo "Will save generated documentation to \"${API_DOCS_DIR}\""
23+echo "Removing old API documentation"
24+rm -r $API_DOCS_DIR/html 2> /dev/null
25+rm -r $API_DOCS_DIR/docset 2> /dev/null
26+
27+echo "Will generate API documentation based on:"
28+echo ${HEADER_FILES}
29+
30+echo "Generating for version \"${PROJECT_VERSION}\"..."
31+appledoc \
32+ --output ${API_DOCS_DIR} \
33+ --project-name "CDEvents" \
34+ --project-version ${PROJECT_VERSION} \
35+ --project-company "Aron Cedercrantz" \
36+ --company-id "com.cedercrantz" \
37+ --create-html \
38+ --keep-intermediate-files \
39+ --no-install-docset \
40+ ${HEADER_FILES}
41+echo "Done!"
42+
43+echo "You can open the HTML documentation with:"
44+echo "\"open ${API_DOCS_DIR}/html/index.html\""
45+