iOS 监听文件目录变化

318 阅读1分钟

实现功能

当监听的目录被删除时,会弹出警告alert框

/// 文件描述符
@property (nonatomic, assign) int fileDescriptor;
/// 信号源
@property (nonatomic, strong) dispatch_source_t source;

/// 监听指定目录
- (void)monitorDir:(NSString *)dir {
    NSLog(@"监听目录: %@", dir);
    _fileDescriptor = open([dir fileSystemRepresentation], O_EVTONLY);
    dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    __weak typeof(self) weakself = self;
    _source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE,
           _fileDescriptor,
           DISPATCH_VNODE_ATTRIB | DISPATCH_VNODE_DELETE | DISPATCH_VNODE_EXTEND | DISPATCH_VNODE_LINK | DISPATCH_VNODE_RENAME | DISPATCH_VNODE_REVOKE | DISPATCH_VNODE_WRITE,
           defaultQueue);
    dispatch_source_set_event_handler(_source, ^{
        unsigned long eventTypes = dispatch_source_get_data(weakself.source);
        NSLog(@"目录发生变化:%@", @(eventTypes));
        [weakself showAlert:eventTypes];
    });

    dispatch_source_set_cancel_handler(_source, ^{
        close(weakself.fileDescriptor);
        weakself.fileDescriptor = 0;
        weakself.source = nil;
    });
    dispatch_resume(_source);
}
/// 弹出警示框
- (void)showAlert:(unsigned long)eventTypes {
    __weak typeof(self) weakself = self;
    dispatch_async(dispatch_get_main_queue(), ^ {
        if ((eventTypes & DISPATCH_VNODE_DELETE) || (eventTypes & DISPATCH_VNODE_RENAME)) {
            dispatch_source_cancel(weakself.source);
            NSString *message = [NSString stringWithFormat:@"%@: 资源目录被非正常删除", [weakself description]];
            NSLog(@"%@", message);
#if (defined DEBUG || defined ADHOC)
            [self showAlertWithTitle:@"警告" message:message];
#endif
        }
    });
}

- (void)showAlertWithTitle:(NSString *)title message:(NSString *)message {
    dispatch_async(dispatch_get_main_queue(), ^{
        UIWindow *window = [UIApplication sharedApplication].delegate.window;
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *ok = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        }];
        [alert addAction:ok];
        
        UIViewController *vc = window.rootViewController;
        if (vc.presentedViewController) {
            vc = vc.presentedViewController;
        }
        [vc presentViewController:alert animated:YES completion:NULL];
    });
}