Skip to content

Instantly share code, notes, and snippets.

@dqhieu
Created March 3, 2024 16:05
Show Gist options
  • Save dqhieu/67359c9020a114dd69a450968e2bd9f3 to your computer and use it in GitHub Desktop.
Save dqhieu/67359c9020a114dd69a450968e2bd9f3 to your computer and use it in GitHub Desktop.
Monitor a folder for new files
import Foundation
class FolderMonitor {
private var monitoredFolderURL: URL
private var folderMonitorQueue: DispatchQueue
private var folderMonitorSource: DispatchSourceFileSystemObject?
private var lastFileList: [String] = []
init(folderURL: URL) {
self.monitoredFolderURL = folderURL
self.folderMonitorQueue = DispatchQueue(label: "FolderMonitorQueue", attributes: .concurrent)
updateLastFileList()
}
private func updateLastFileList() {
do {
let fileList = try FileManager.default.contentsOfDirectory(atPath: monitoredFolderURL.path)
self.lastFileList = fileList
} catch {
print("Failed to fetch file list: \(error)")
}
}
func startMonitoring(completion: @escaping (String) -> Void) {
let fileDescriptor = open(monitoredFolderURL.path, O_EVTONLY)
guard fileDescriptor != -1 else {
print("Unable to open file descriptor.")
return
}
folderMonitorSource = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fileDescriptor, eventMask: .write, queue: folderMonitorQueue)
folderMonitorSource?.setEventHandler { [weak self] in
guard let self = self else { return }
do {
let currentFileList = try FileManager.default.contentsOfDirectory(atPath: self.monitoredFolderURL.path)
let newFiles = currentFileList.filter { !self.lastFileList.contains($0) }
self.lastFileList = currentFileList // Update the last known file list
// Notify for each new file found
newFiles.forEach { newFile in
let fullPath = self.monitoredFolderURL.appendingPathComponent(newFile).path
completion(fullPath)
}
} catch {
print("Error listing directory contents: \(error)")
}
}
folderMonitorSource?.setCancelHandler {
close(fileDescriptor)
}
folderMonitorSource?.resume()
}
func stopMonitoring() {
folderMonitorSource?.cancel()
folderMonitorSource = nil
}
}
// Example usage
let folderURL = URL(fileURLWithPath: "/path/to/your/folder")
let folderMonitor = FolderMonitor(folderURL: folderURL)
folderMonitor.startMonitoring { filePath in
print("A new file has been created at: \(filePath)")
}
// To stop monitoring, you can call:
// folderMonitor.stopMonitoring()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment