You can use the GCD sending source mechanism - using it, you can observe certain system events (in your case, these are events of the vnode type, since you are working with the file system). To configure the observer for a specific directory, I used this code:
- (dispatch_source_t) fileSystemDispatchSourceAtPath:(NSString*) path { int fileDescr = open([path fileSystemRepresentation], O_EVTONLY);// observe file system events for particular path - you can pass here Documents directory path //observer queue is my private dispatch_queue_t object dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fileDescr, DISPATCH_VNODE_ATTRIB| DISPATCH_VNODE_WRITE|DISPATCH_VNODE_LINK|DISPATCH_VNODE_EXTEND, observerQueue);// create dispatch_source object to observe vnode events dispatch_source_set_registration_handler(source, ^{ NSLog(@"registered for observation"); //event handler is called each time file system event of selected type (DISPATCH_VNODE_*) has occurred dispatch_source_set_event_handler(source, ^{ dispatch_source_vnode_flags_t flags = dispatch_source_get_data(source);//obtain flags NSLog(@"%lu",flags); if(flags & DISPATCH_VNODE_WRITE)//flag is set to DISPATCH_VNODE_WRITE every time data is appended to file { NSLog(@"DISPATCH_VNODE_WRITE"); NSDictionary* dict = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil]; float size = [[dict valueForKey:NSFileSize] floatValue]; NSLog(@"%f",size); } if(flags & DISPATCH_VNODE_ATTRIB)//this flag is passed when file is completely written. { NSLog(@"DISPATCH_VNODE_ATTRIB"); dispatch_source_cancel(source); } if(flags & DISPATCH_VNODE_LINK) { NSLog(@"DISPATCH_VNODE_LINK"); } if(flags & DISPATCH_VNODE_EXTEND) { NSLog(@"DISPATCH_VNODE_EXTEND"); } NSLog(@"file = %@",path); NSLog(@"\n\n"); }); dispatch_source_set_cancel_handler(source, ^{ close(fileDescr); }); }); //we have to resume dispatch_objects dispatch_resume(source); return source; } , DISPATCH_VNODE_ATTRIB | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_LINK | DISPATCH_VNODE_EXTEND, observerQueue); // create dispatch_source object to observe vnode events - (dispatch_source_t) fileSystemDispatchSourceAtPath:(NSString*) path { int fileDescr = open([path fileSystemRepresentation], O_EVTONLY);// observe file system events for particular path - you can pass here Documents directory path //observer queue is my private dispatch_queue_t object dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fileDescr, DISPATCH_VNODE_ATTRIB| DISPATCH_VNODE_WRITE|DISPATCH_VNODE_LINK|DISPATCH_VNODE_EXTEND, observerQueue);// create dispatch_source object to observe vnode events dispatch_source_set_registration_handler(source, ^{ NSLog(@"registered for observation"); //event handler is called each time file system event of selected type (DISPATCH_VNODE_*) has occurred dispatch_source_set_event_handler(source, ^{ dispatch_source_vnode_flags_t flags = dispatch_source_get_data(source);//obtain flags NSLog(@"%lu",flags); if(flags & DISPATCH_VNODE_WRITE)//flag is set to DISPATCH_VNODE_WRITE every time data is appended to file { NSLog(@"DISPATCH_VNODE_WRITE"); NSDictionary* dict = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil]; float size = [[dict valueForKey:NSFileSize] floatValue]; NSLog(@"%f",size); } if(flags & DISPATCH_VNODE_ATTRIB)//this flag is passed when file is completely written. { NSLog(@"DISPATCH_VNODE_ATTRIB"); dispatch_source_cancel(source); } if(flags & DISPATCH_VNODE_LINK) { NSLog(@"DISPATCH_VNODE_LINK"); } if(flags & DISPATCH_VNODE_EXTEND) { NSLog(@"DISPATCH_VNODE_EXTEND"); } NSLog(@"file = %@",path); NSLog(@"\n\n"); }); dispatch_source_set_cancel_handler(source, ^{ close(fileDescr); }); }); //we have to resume dispatch_objects dispatch_resume(source); return source; }
source share