I created an FSEvent to handle the file changes. My problem is that the first time I save the file (it happens with Microsoft files, for example “.docx”, “.xls”… files) the event is fired twice. I need to display a user message, and it is displayed twice. Here is my source code:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *application_directory = [paths objectAtIndex:0];
NSString *folder_path = [NSString stringWithFormat:@"%@/%@", application_directory, path];
CFStringRef file_path_ref = (CFStringRef) folder_path;
CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&file_path_ref, 1, NULL);
void *appPointer = (void *)self;
FSEventStreamContext context = {0, appPointer, NULL, NULL, NULL}; // could put stream-specific data here.
CFAbsoluteTime latency = 3.0; /* Latency in seconds */
//Create the stream, passing in a callback
stream = FSEventStreamCreate(NULL,
&mycallback,
&context,
pathsToWatch,
kFSEventStreamEventIdSinceNow,
latency,
kFSEventStreamCreateFlagUseCFTypes
);
FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
FSEventStreamStart(stream);
CFRunLoopRun();
And this is the callback method:
void mycallback(ConstFSEventStreamRef streamRef,
void *clientCallBackInfo,
size_t numEvents,
void *eventPaths,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[]){
int i;
for (i=0; i<numEvents; i++)
{
DirectoryWatcher *directory_watcher = (DirectoryWatcher *)clientCallBackInfo;
NSFileManager *file_manager = [NSFileManager defaultManager];
Common *common = [[Common alloc] init];
NSString *file_path = [common filePathByNameAndId:directory_watcher.file_name file_id:directory_watcher.file_id];
NSDictionary *fileAttributes = [file_manager attributesOfItemAtPath:file_path error:NULL];
[common release];
NSDate *modified_date = [fileAttributes objectForKey:@"NSFileModificationDate"];
NSDate *saved_date = [[NSUserDefaults standardUserDefaults] objectForKey:@"kFeedLastModified"];
[[NSUserDefaults standardUserDefaults] setObject:modified_date forKey:@"kFeedLastModified"];
[[NSUserDefaults standardUserDefaults] synchronize];
if (![modified_date isEqualToDate: saved_date])
{
Common *common = [[Common alloc] init];
if([common networkConectivityAvailable])
{
//HERE IS MY USER MESSAGE
}
else
{
NSLog(@"Retry this flow when internet is restored.");
}
[common release];
}
} }
Sounds like Microsoft is doing some goofy stuff when writing out files… and actually, you can never count on every app behaving consistently and/or properly.
My suggestion would be to only display an alert if one isn’t already displaying (i.e. that would get rid of the issue of multiple FSEvents firing from Microsoft apps). Or queue up the alerts and display them in order, making sure to display a subsequent alert only when appropriate (i.e. when a certain amount of time has passed or if the subsequent action is on a different file, etc.).