An Objective-C wrapper for Mac OS X’s FSEvents C API.
Revision | b0699d26646c7c51cd91f31a04f0f8b7f61a273a (tree) |
---|---|
Time | 2010-04-04 05:01:19 |
Author | Aron Cedercrantz <aron@cede...> |
Commiter | Aron Cedercrantz |
Merge branch 'release/1.0.0'
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 | +} |
@@ -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 | + |
@@ -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> |
@@ -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 |
@@ -0,0 +1,2 @@ | ||
1 | +/* Localized versions of Info.plist keys */ | |
2 | + |
@@ -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> |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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> |