UIFileSharingEnabled = YES
But this is not even half the battle. The point is that, in an amicable way, the application should now monitor all changes with files occurring in the Documents directory and update its data accordingly. How to release it in your code and tell this article.
dispatch_source_create
using dispatch_source_create
, the source of which will be the file descriptor (directory file descriptor), and the event itself (file recording) will work out the necessary block for updating the application data.
startMonitor
and stopMonitor
, respectively, launching and stopping the monitoring of the directory we need, as well as a couple of subsidiary methods for checking changes in this directory that will be launched through the handler block.
- (void)startMonitor { // dispatch_source_t if (_src != NULL) return; // Documents NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; // , (O_EVTONLY) _fileDescriptor = open([docPath fileSystemRepresentation], O_EVTONLY); // thread, UI dispatch_queue_t queue = dispatch_get_main_queue(); // dispatch source (write) _src = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, _fileDescriptor, DISPATCH_VNODE_WRITE, queue); // handler block dispatch_source_set_event_handler(_src, ^{ [self directoryDidChange]; }); // dispatch_source_set_cancel_handler(_src, ^{ close(_fileDescriptor); }); dispatch_resume(_src); } - (void)stopMonitor { if (_src) { // , dispatch_source_cancel(_src); _src = NULL; } } - (void)directoryDidChange { if(!waitingForDocumentsDirectoryTimeout) { // , , waitingForDocumentsDirectoryTimeout = YES; // _lastDocumentsDirectoryReferenceArray=[self documentsDirectoryReferenceArray]; //... , [self performSelector:@selector(checkForDocumentsDirectoryChanges) withObject:nil afterDelay:1.0 inModes:[NSArray arrayWithObjects:NSRunLoopCommonModes,nil]]; } } -(void)checkForDocumentsDirectoryChanges { NSArray *newDocumentsDirectoryReferenceArray=[self documentsDirectoryReferenceArray]; // if(![newDocumentsDirectoryReferenceArray isEqualToArray:_lastDocumentsDirectoryReferenceArray]) { // _lastDocumentsDirectoryReferenceArray=newDocumentsDirectoryReferenceArray; [self performSelector:@selector(checkForDocumentsDirectoryChanges) withObject:nil afterDelay:1.0 inModes:[NSArray arrayWithObjects:NSRunLoopCommonModes,nil]]; } else { // waitingForDocumentsDirectoryTimeout=NO; _lastDocumentsDirectoryReferenceArray=nil; // ... , [self scanDocumentsDirectory]; } } -(NSArray *)documentsDirectoryReferenceArray { // - NSString *documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSArray *documentsDirectoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectoryPath error:NULL]; NSMutableArray *documentsDirectoryReferenceArray=[NSMutableArray arrayWithCapacity:10]; for(NSString *fileName in documentsDirectoryContents){ NSString *filePath=[documentsDirectoryPath stringByAppendingPathComponent:fileName]; NSError *error; NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:&error]; NSInteger fileSize = [[fileAttributes objectForKey:NSFileSize] intValue]; NSString *fileWithLength=[NSString stringWithFormat:@"%@-%d",fileName,fileSize]; [documentsDirectoryReferenceArray addObject:fileWithLength]; } return documentsDirectoryReferenceArray; }
DTFolderMonitor
.
scanDocumentsDirectory
, besides monitoring, as soon as the application becomes active. Its purpose is not only to check, but also to update the data about the files in the application with their actual presence in the directory, since the synchronization of files with iTunes can occur even while the application is in the background or is not started at all.
- (void)applicationWillEnterForeground:(UIApplication *)application { [self scanDocumentsDirectory]; }
Source: https://habr.com/ru/post/191868/