An Objective-C wrapper for Mac OS X’s FSEvents C API.
Revisão | 79c2467b9f4ffdde60ba411813a52db75bdcd157 (tree) |
---|---|
Hora | 2010-04-10 23:29:31 |
Autor | Aron Cedercrantz <aron@cede...> |
Commiter | Aron Cedercrantz |
Merge branch 'release/1.1.0'
@@ -119,6 +119,238 @@ typedef FSEventStreamEventFlags CDEventFlags; | ||
119 | 119 | */ |
120 | 120 | @property (readonly) CDEventFlags flags; |
121 | 121 | |
122 | +#pragma mark Specific flag properties | |
123 | +/** | |
124 | + * Wheter there was some change in the directory at the specific path supplied in this event. | |
125 | + * | |
126 | + * @return <code>YES</code> if there was some change in the directory, otherwise <code>NO</code> | |
127 | + * | |
128 | + * @see kFSEventStreamEventFlagNone | |
129 | + * @see flags | |
130 | + * @see mustRescanSubDirectories | |
131 | + * @see isUserDropped | |
132 | + * @see isKernelDropped | |
133 | + * @see isEventIdsWrapped | |
134 | + * @see isHistoryDone | |
135 | + * @see isRootChanged | |
136 | + * @see didVolumeMount | |
137 | + * @see didVolumeUnmount | |
138 | + * | |
139 | + * @since 1.1.0 | |
140 | + */ | |
141 | +@property (readonly) BOOL isGenericChange; | |
142 | + | |
143 | +/** | |
144 | + * Wheter you must rescan the whole URL including its children. | |
145 | + * | |
146 | + * Wheter your application must rescan not just the URL given in the event, but | |
147 | + * all its children, recursively. This can happen if there was a problem whereby | |
148 | + * events were coalesced hierarchically. For example, an event in | |
149 | + * <code>/Users/jsmith/Music</code> and an event in | |
150 | + * <code>/Users/jsmith/Pictures</code> might be coalesced into an event with | |
151 | + * this flag set and <i>URL</i><code>=/Users/jsmith</code>. If this flag is set | |
152 | + * you may be able to get an idea of whether the bottleneck happened in the | |
153 | + * kernel (less likely) or in your client (more likely) by checking if | |
154 | + * flagUserDropped or flagKernelDropped returns <code>YES</code>. | |
155 | + * | |
156 | + * @return <code>YES</code> if you must rescan the whole directory including its children, otherwise <code>NO</code> | |
157 | + * | |
158 | + * @see kFSEventStreamEventFlagMustScanSubDirs | |
159 | + * @see flags | |
160 | + * @see isGenericChange | |
161 | + * @see isUserDropped | |
162 | + * @see isKernelDropped | |
163 | + * @see isEventIdsWrapped | |
164 | + * @see isHistoryDone | |
165 | + * @see isRootChanged | |
166 | + * @see didVolumeMount | |
167 | + * @see didVolumeUnmount | |
168 | + * | |
169 | + * @since 1.1.0 | |
170 | + */ | |
171 | +@property (readonly) BOOL mustRescanSubDirectories; | |
172 | + | |
173 | +/** | |
174 | + * Provides some information as to what might have caused the need to rescan the URL including its children. | |
175 | + * | |
176 | + * @return <code>YES</code> if mustRescanSubDirectories returns <code>YES</code> and the cause were in userland, otherwise <code>NO</code> | |
177 | + * | |
178 | + * @see kFSEventStreamEventFlagUserDropped | |
179 | + * @see flags | |
180 | + * @see isGenericChange | |
181 | + * @see mustRescanSubDirectories | |
182 | + * @see isKernelDropped | |
183 | + * @see isEventIdsWrapped | |
184 | + * @see isHistoryDone | |
185 | + * @see isRootChanged | |
186 | + * @see didVolumeMount | |
187 | + * @see didVolumeUnmount | |
188 | + * | |
189 | + * @since 1.1.0 | |
190 | + */ | |
191 | +@property (readonly) BOOL isUserDropped; | |
192 | + | |
193 | +/** | |
194 | + * Provides some information as to what might have caused the need to rescan the URL including its children. | |
195 | + * | |
196 | + * @return <code>YES</code> if mustRescanSubDirectories returns <code>YES</code> and the cause were in kernelspace, otherwise <code>NO</code> | |
197 | + * | |
198 | + * @see kFSEventStreamEventFlagKernelDropped | |
199 | + * @see flags | |
200 | + * @see isGenericChange | |
201 | + * @see mustRescanSubDirectories | |
202 | + * @see isUserDropped | |
203 | + * @see isEventIdsWrapped | |
204 | + * @see isHistoryDone | |
205 | + * @see isRootChanged | |
206 | + * @see didVolumeMount | |
207 | + * @see didVolumeUnmount | |
208 | + * | |
209 | + * @since 1.1.0 | |
210 | + */ | |
211 | +@property (readonly) BOOL isKernelDropped; | |
212 | + | |
213 | +/** | |
214 | + * Wheter the 64-bit event identifier counter has wrapped around. | |
215 | + * | |
216 | + * Wheter the 64-bit event identifier counter has wrapped around. As a result, | |
217 | + * previously-issued event identifiers are no longer valid arguments for the | |
218 | + * sinceEventIdentifier parameter of the CDEvents init methods. | |
219 | + * | |
220 | + * @return <code>YES</code> if the 64-bit event identifier counter has wrapped around, otherwise <code>NO</code> | |
221 | + * | |
222 | + * @see kFSEventStreamEventFlagEventIdsWrapped | |
223 | + * @see flags | |
224 | + * @see isGenericChange | |
225 | + * @see mustRescanSubDirectories | |
226 | + * @see isUserDropped | |
227 | + * @see isKernelDropped | |
228 | + * @see isHistoryDone | |
229 | + * @see isRootChanged | |
230 | + * @see didVolumeMount | |
231 | + * @see didVolumeUnmount | |
232 | + * | |
233 | + * @since 1.1.0 | |
234 | + */ | |
235 | +@property (readonly) BOOL isEventIdentifiersWrapped; | |
236 | + | |
237 | +/** | |
238 | + * Denotes a sentinel event sent to mark the end of the "historical" events sent. | |
239 | + * | |
240 | + * Denotes a sentinel event sent to mark the end of the "historical" events sent | |
241 | + * as a result of specifying a <i>sinceEventIdentifier</i> argument other than | |
242 | + * kCDEventsSinceEventNow with the CDEvents init methods. | |
243 | + * | |
244 | + * @return <code>YES</code> if if the event is sent to mark the end of the "historical" events sent, otherwise <code>NO</code> | |
245 | + * | |
246 | + * @see kFSEventStreamEventFlagHistoryDone | |
247 | + * @see flags | |
248 | + * @see isGenericChange | |
249 | + * @see mustRescanSubDirectories | |
250 | + * @see isUserDropped | |
251 | + * @see isKernelDropped | |
252 | + * @see isEventIdsWrapped | |
253 | + * @see isRootChanged | |
254 | + * @see didVolumeMount | |
255 | + * @see didVolumeUnmount | |
256 | + * @see kCDEventsSinceEventNow | |
257 | + * @see CDEvents | |
258 | + * | |
259 | + * @since 1.1.0 | |
260 | + */ | |
261 | +@property (readonly) BOOL isHistoryDone; | |
262 | + | |
263 | +/** | |
264 | + * Denotes a special event sent when there is a change to one of the URLs you asked to watch. | |
265 | + * | |
266 | + * Denotes a special event sent when there is a change to one of the URLs you | |
267 | + * asked to watch. When this method returns <code>YES</code>, the event | |
268 | + * identifier is zero and the <code>URL</code> corresponds to one of the URLs | |
269 | + * you asked to watch (specifically, the one that changed). The URL may no | |
270 | + * longer exist because it or one of its parents was deleted or renamed. Events | |
271 | + * with this flag set will only be sent if you passed the flag | |
272 | + * <code>kFSEventStreamCreateFlagWatchRoot</code> to the CDEvents. | |
273 | + * | |
274 | + * @return <code>YES</code> if there is a change to one of the URLs you asked to watch, otherwise <code>NO</code> | |
275 | + * | |
276 | + * @see kFSEventStreamEventFlagRootChanged | |
277 | + * @see flags | |
278 | + * @see isGenericChange | |
279 | + * @see mustRescanSubDirectories | |
280 | + * @see isUserDropped | |
281 | + * @see isKernelDropped | |
282 | + * @see isEventIdsWrapped | |
283 | + * @see isHistoryDone | |
284 | + * @see didVolumeMount | |
285 | + * @see didVolumeUnmount | |
286 | + * @see CDEvents | |
287 | + * @see kCDEventsDefaultEventStreamFlags | |
288 | + * | |
289 | + * @since 1.1.0 | |
290 | + */ | |
291 | +@property (readonly) BOOL isRootChanged; | |
292 | + | |
293 | +/** | |
294 | + * Denotes a special event sent when a volume is mounted underneath one of the URLs being watched. | |
295 | + * | |
296 | + * Denotes a special event sent when a volume is mounted underneath one of the | |
297 | + * URLs being watched. The URL in the event is the URL to the newly-mounted | |
298 | + * volume. You will receive one of these notifications for every volume mount | |
299 | + * event inside the kernel (independent of DiskArbitration). Beware that a | |
300 | + * newly-mounted volume could contain an arbitrarily large directory hierarchy. | |
301 | + * Avoid pitfalls like triggering a recursive scan of a non-local filesystem, | |
302 | + * which you can detect by checking for the absence of the | |
303 | + * <code>MNT_LOCAL</code> flag in the <code>f_flags</code> returned by statfs(). | |
304 | + * Also be aware of the <code>MNT_DONTBROWSE</code> flag that is set for volumes | |
305 | + * which should not be displayed by user interface elements. | |
306 | + * | |
307 | + * @return <code>YES</code> if a volumen is mounted underneath one of the URLs being watched, otherwise <code>NO</code> | |
308 | + * | |
309 | + * @see kFSEventStreamEventFlagMount | |
310 | + * @see flags | |
311 | + * @see isGenericChange | |
312 | + * @see mustRescanSubDirectories | |
313 | + * @see isUserDropped | |
314 | + * @see isKernelDropped | |
315 | + * @see isEventIdsWrapped | |
316 | + * @see isHistoryDone | |
317 | + * @see isRootChanged | |
318 | + * @see didVolumeUnmount | |
319 | + * | |
320 | + * @since 1.1.0 | |
321 | + */ | |
322 | +@property (readonly) BOOL didVolumeMount; | |
323 | + | |
324 | +/** | |
325 | + * Denotes a special event sent when a volume is unmounted underneath one of the URLs being watched. | |
326 | + * | |
327 | + * Denotes a special event sent when a volume is unmounted underneath one of the | |
328 | + * URLs being watched. The URL in the event is the URL to the directory from | |
329 | + * which the volume was unmounted. You will receive one of these notifications | |
330 | + * for every volume unmount event inside the kernel. This is not a substitute | |
331 | + * for the notifications provided by the DiskArbitration framework; you only get | |
332 | + * notified after the unmount has occurred. Beware that unmounting a volume | |
333 | + * could uncover an arbitrarily large directory hierarchy, although Mac OS X | |
334 | + * never does that. | |
335 | + * | |
336 | + * @return <code>YES</code> if a volume is unmounted underneath one of the URLs being watched, otherwise <code>NO</code> | |
337 | + * | |
338 | + * @see kFSEventStreamEventFlagUnmount | |
339 | + * @see flags | |
340 | + * @see isGenericChange | |
341 | + * @see mustRescanSubDirectories | |
342 | + * @see isUserDropped | |
343 | + * @see isKernelDropped | |
344 | + * @see isEventIdsWrapped | |
345 | + * @see isHistoryDone | |
346 | + * @see isRootChanged | |
347 | + * @see didVolumeMount | |
348 | + * | |
349 | + * @since 1.1.0 | |
350 | + */ | |
351 | +@property (readonly) BOOL didVolumeUnmount; | |
352 | + | |
353 | + | |
122 | 354 | #pragma mark Class object creators |
123 | 355 | |
124 | 356 | /** |
@@ -53,7 +53,6 @@ | ||
53 | 53 | |
54 | 54 | |
55 | 55 | #pragma mark Init/dealloc methods |
56 | - | |
57 | 56 | - (void)dealloc |
58 | 57 | { |
59 | 58 | [_date release]; |
@@ -79,7 +78,6 @@ | ||
79 | 78 | |
80 | 79 | |
81 | 80 | #pragma mark NSCoding methods |
82 | - | |
83 | 81 | - (void)encodeWithCoder:(NSCoder *)aCoder |
84 | 82 | { |
85 | 83 | [aCoder encodeObject:[NSNumber numberWithUnsignedInteger:[self identifier]] forKey:@"identifier"]; |
@@ -98,16 +96,62 @@ | ||
98 | 96 | return self; |
99 | 97 | } |
100 | 98 | |
101 | -#pragma mark NSCopying methods | |
102 | 99 | |
100 | +#pragma mark NSCopying methods | |
103 | 101 | - (id)copyWithZone:(NSZone *)zone |
104 | 102 | { |
105 | 103 | // We can do this since we are immutable. |
106 | 104 | return [self retain]; |
107 | 105 | } |
108 | 106 | |
109 | -#pragma mark Public API | |
110 | 107 | |
108 | +#pragma mark Specific flag properties | |
109 | +- (BOOL)isGenericChange | |
110 | +{ | |
111 | + return (kFSEventStreamEventFlagNone == _flags); | |
112 | +} | |
113 | + | |
114 | +- (BOOL)mustRescanSubDirectories | |
115 | +{ | |
116 | + return (_flags & kFSEventStreamEventFlagMustScanSubDirs); | |
117 | +} | |
118 | + | |
119 | +- (BOOL)isUserDropped | |
120 | +{ | |
121 | + return (_flags & kFSEventStreamEventFlagUserDropped); | |
122 | +} | |
123 | + | |
124 | +- (BOOL)isKernelDropped | |
125 | +{ | |
126 | + return (_flags & kFSEventStreamEventFlagKernelDropped); | |
127 | +} | |
128 | + | |
129 | +- (BOOL)isEventIdentifiersWrapped | |
130 | +{ | |
131 | + return (_flags & kFSEventStreamEventFlagEventIdsWrapped); | |
132 | +} | |
133 | + | |
134 | +- (BOOL)isHistoryDone | |
135 | +{ | |
136 | + return (_flags & kFSEventStreamEventFlagHistoryDone); | |
137 | +} | |
138 | + | |
139 | +- (BOOL)isRootChanged | |
140 | +{ | |
141 | + return (_flags & kFSEventStreamEventFlagRootChanged); | |
142 | +} | |
143 | + | |
144 | +- (BOOL)didVolumeMount | |
145 | +{ | |
146 | + return (_flags & kFSEventStreamEventFlagMount); | |
147 | +} | |
148 | + | |
149 | +- (BOOL)didVolumeUnmount | |
150 | +{ | |
151 | + return (_flags & kFSEventStreamEventFlagUnmount); | |
152 | +} | |
153 | + | |
154 | +#pragma mark Misc | |
111 | 155 | - (NSString *)description |
112 | 156 | { |
113 | 157 | return [NSString stringWithFormat:@"<%@: %p { identifier = %ld, URL = %@, flags = %ld, date = %@ }>", |
@@ -84,10 +84,17 @@ extern NSString *const CDEventsEventStreamCreationFailureException; | ||
84 | 84 | * |
85 | 85 | * @since 1.0.0 |
86 | 86 | */ |
87 | -const NSUInteger kCDEventsDefaultEventStreamFlags = | |
87 | +const CDEventsEventStreamCreationFlags kCDEventsDefaultEventStreamFlags = | |
88 | 88 | (kFSEventStreamCreateFlagUseCFTypes | |
89 | 89 | kFSEventStreamCreateFlagWatchRoot); |
90 | 90 | |
91 | +/** | |
92 | + * Use this to get all event since now when initializing a CDEvents object. | |
93 | + * | |
94 | + * @since 1.1.0 | |
95 | + */ | |
96 | +const CDEventIdentifier kCDEventsSinceEventNow = kFSEventStreamEventIdSinceNow; | |
97 | + | |
91 | 98 | |
92 | 99 | #pragma mark - |
93 | 100 | #pragma mark CDEvents interface |
@@ -198,19 +205,6 @@ const NSUInteger kCDEventsDefaultEventStreamFlags = | ||
198 | 205 | */ |
199 | 206 | + (CDEventIdentifier)currentEventIdentifier; |
200 | 207 | |
201 | -/** | |
202 | - * The last event identifier for the given device that was returned before the given date and time | |
203 | - * | |
204 | - * @param URL The URL of the item the event identifier is sought for, used to find the device. | |
205 | - * @param time The date and time. | |
206 | - * @return The last event identifier for the given URL that was returned before the given time | |
207 | - * | |
208 | - * @see FSEventsGetLastEventIdForDeviceBeforeTime(dev_t, CFAbsoluteTime) | |
209 | - * | |
210 | - * @since 1.1.0 | |
211 | - */ | |
212 | -+ (CDEventIdentifier)lastEventIdentifierForURL:(NSURL *)URL time:(NSDate *)time; | |
213 | - | |
214 | 208 | |
215 | 209 | #pragma mark Init methods |
216 | 210 | /** |
@@ -226,10 +220,11 @@ const NSUInteger kCDEventsDefaultEventStreamFlags = | ||
226 | 220 | * @see initWithURLs:delegate:onRunLoop: |
227 | 221 | * @see initWithURLs:delegate:onRunLoop:notificationLantency:ignoreEventsFromSubDirs:excludeURLs:streamCreationFlags: |
228 | 222 | * @see kCDEventsDefaultEventStreamFlags |
223 | + * @see kCDEventsSinceEventNow | |
229 | 224 | * |
230 | 225 | * @discussion Calls startWatchingURLs:onRunLoop:notificationLantency:ignoreEventsFromSubDirs:excludeURLs:streamCreationFlags: |
231 | - * with <em>sinceEventIdentifier</em> with the current event identifier, | |
232 | - * <em>notificationLatency</em> set to 3.0 seconds, | |
226 | + * with <em>sinceEventIdentifier</em> with the event identifier for "event since | |
227 | + * now", <em>notificationLatency</em> set to 3.0 seconds, | |
233 | 228 | * <em>ignoreEventsFromSubDirectories</em> set to <code>NO</code>, |
234 | 229 | * <em>excludedURLs</em> to no URLs, the event stream creation flags will be set |
235 | 230 | * to <code>kCDEventsDefaultEventStreamFlags</code> and schedueled on the |
@@ -253,13 +248,14 @@ const NSUInteger kCDEventsDefaultEventStreamFlags = | ||
253 | 248 | * @see initWithURLs: |
254 | 249 | * @see initWithURLs:onRunLoop:notificationLantency:ignoreEventsFromSubDirs:excludeURLs:streamCreationFlags: |
255 | 250 | * @see kCDEventsDefaultEventStreamFlags |
251 | + * @see kCDEventsSinceEventNow | |
256 | 252 | * |
257 | 253 | * @discussion Calls startWatchingURLs:onRunLoop:notificationLantency:ignoreEventsFromSubDirs:excludeURLs:streamCreationFlags: |
258 | 254 | * with <em>runLoop</em> set to the current run loop, <em>sinceEventIdentifier</em> |
259 | - * with the current event identifier, <em>notificationLatency</em> set to 3.0 | |
260 | - * seconds, <em>ignoreEventsFromSubDirectories</em> set to <code>NO</code>, | |
261 | - * <em>excludedURLs</em> to no URLs and the event stream creation flags will be | |
262 | - * set to <code>kCDEventsDefaultEventStreamFlags</code>. | |
255 | + * with the event identifier for "event since now", <em>notificationLatency</em> | |
256 | + * set to 3.0 seconds, <em>ignoreEventsFromSubDirectories</em> set to | |
257 | + * <code>NO</code>, <em>excludedURLs</em> to no URLs and the event stream | |
258 | + * creation flags will be set to <code>kCDEventsDefaultEventStreamFlags</code>. | |
263 | 259 | * |
264 | 260 | * @since 1.0.0 |
265 | 261 | */ |
@@ -94,7 +94,7 @@ static void CDEventsCallback( | ||
94 | 94 | return [self initWithURLs:URLs |
95 | 95 | delegate:delegate |
96 | 96 | onRunLoop:runLoop |
97 | - sinceEventIdentifier:[CDEvents currentEventIdentifier] | |
97 | + sinceEventIdentifier:kCDEventsSinceEventNow | |
98 | 98 | notificationLantency:CD_EVENTS_DEFAULT_NOTIFICATION_LATENCY |
99 | 99 | ignoreEventsFromSubDirs:CD_EVENTS_DEFAULT_IGNORE_EVENT_FROM_SUB_DIRS |
100 | 100 | excludeURLs:nil |
@@ -325,6 +325,7 @@ | ||
325 | 325 | GCC_OPTIMIZATION_LEVEL = 0; |
326 | 326 | GCC_PRECOMPILE_PREFIX_HEADER = YES; |
327 | 327 | GCC_PREFIX_HEADER = CDEvents_Prefix.pch; |
328 | + GCC_PREPROCESSOR_DEFINITIONS = NS_BUILD_32_LIKE_64; | |
328 | 329 | GCC_VERSION = ""; |
329 | 330 | INFOPLIST_FILE = Info.plist; |
330 | 331 | INSTALL_PATH = "@loader_path/../Frameworks"; |
@@ -345,6 +346,7 @@ | ||
345 | 346 | GCC_MODEL_TUNING = G5; |
346 | 347 | GCC_PRECOMPILE_PREFIX_HEADER = YES; |
347 | 348 | GCC_PREFIX_HEADER = CDEvents_Prefix.pch; |
349 | + GCC_PREPROCESSOR_DEFINITIONS = NS_BUILD_32_LIKE_64; | |
348 | 350 | GCC_VERSION = ""; |
349 | 351 | INFOPLIST_FILE = Info.plist; |
350 | 352 | INSTALL_PATH = "@loader_path/../Frameworks"; |
@@ -401,6 +403,7 @@ | ||
401 | 403 | GCC_OPTIMIZATION_LEVEL = 0; |
402 | 404 | GCC_PRECOMPILE_PREFIX_HEADER = YES; |
403 | 405 | GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; |
406 | + GCC_PREPROCESSOR_DEFINITIONS = NS_BUILD_32_LIKE_64; | |
404 | 407 | INFOPLIST_FILE = "CDEventsTestApp-Info.plist"; |
405 | 408 | INSTALL_PATH = "$(HOME)/Applications"; |
406 | 409 | OTHER_LDFLAGS = ( |
@@ -425,6 +428,7 @@ | ||
425 | 428 | GCC_MODEL_TUNING = G5; |
426 | 429 | GCC_PRECOMPILE_PREFIX_HEADER = YES; |
427 | 430 | GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; |
431 | + GCC_PREPROCESSOR_DEFINITIONS = NS_BUILD_32_LIKE_64; | |
428 | 432 | INFOPLIST_FILE = "CDEventsTestApp-Info.plist"; |
429 | 433 | INSTALL_PATH = "$(HOME)/Applications"; |
430 | 434 | OTHER_LDFLAGS = ( |
@@ -21,7 +21,7 @@ | ||
21 | 21 | <key>CFBundleSignature</key> |
22 | 22 | <string>????</string> |
23 | 23 | <key>CFBundleVersion</key> |
24 | - <string>1.0.3</string> | |
24 | + <string>1.1.0</string> | |
25 | 25 | <key>NSPrincipalClass</key> |
26 | 26 | <string></string> |
27 | 27 | </dict> |