Created
July 15, 2020 10:02
-
-
Save fpiraneo/9fa35b82e8f54374be83e7fc5430d467 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Copyright (C) 2016 Apple Inc. All Rights Reserved. | |
See LICENSE.txt for this sample’s licensing information | |
Partially modified by Francesco Piraneo G. | |
Original url: https://github.com/robovm/apple-ios-samples/blob/master/ListerforwatchOSiOSandOSX/Swift/ListerKit/DirectoryMonitor.swift | |
Abstract: | |
`DirectoryMonitor` is used to monitor the contents of the provided directory by using a GCD dispatch source. | |
*/ | |
import Foundation | |
/// A protocol that allows delegates of `DirectoryMonitor` to respond to changes in a directory. | |
protocol DirectoryMonitorDelegate: class { | |
func directoryMonitorDidObserveChange(directoryMonitor: DirectoryMonitor) | |
} | |
class DirectoryMonitor { | |
// MARK: Properties | |
/// The `DirectoryMonitor`'s delegate who is responsible for responding to `DirectoryMonitor` updates. | |
weak var delegate: DirectoryMonitorDelegate? | |
/// A file descriptor for the monitored directory. | |
private var monitoredDirectoryFileDescriptor: CInt = -1 | |
/// A dispatch queue used for sending file changes in the directory. | |
private let directoryMonitorQueue = DispatchQueue(label: "ch.zriemann.AnoniCloud-Connect.DirectoryMonitor", attributes: .concurrent) | |
/// A dispatch source to monitor a file descriptor created from the directory. | |
private var directoryMonitorSource: DispatchSource? | |
/// URL for the directory being monitored. | |
private var url: URL? | |
// MARK: Monitoring | |
func startMonitoring(_ url: URL) { | |
// Listen for changes to the directory (if we are not already). | |
if directoryMonitorSource == nil && monitoredDirectoryFileDescriptor == -1 { | |
// Save actual monitoring URL | |
self.url = url | |
// Open the directory referenced by URL for monitoring only. | |
monitoredDirectoryFileDescriptor = open((url as NSURL).fileSystemRepresentation, O_EVTONLY) | |
// Define a dispatch source monitoring the directory for additions, deletions, and renamings. | |
directoryMonitorSource = DispatchSource.makeFileSystemObjectSource(fileDescriptor: monitoredDirectoryFileDescriptor, eventMask: DispatchSource.FileSystemEvent.write, queue: directoryMonitorQueue) as? DispatchSource | |
// Define the block to call when a file change is detected. | |
directoryMonitorSource?.setEventHandler{ | |
// Call out to the `DirectoryMonitorDelegate` so that it can react appropriately to the change. | |
self.delegate?.directoryMonitorDidObserveChange(directoryMonitor: self) | |
} | |
// Define a cancel handler to ensure the directory is closed when the source is cancelled. | |
directoryMonitorSource?.setCancelHandler{ | |
close(self.monitoredDirectoryFileDescriptor) | |
self.monitoredDirectoryFileDescriptor = -1 | |
self.directoryMonitorSource = nil | |
} | |
// Start monitoring the directory via the source. | |
directoryMonitorSource?.resume() | |
} else { | |
directoryMonitorSource?.cancel() | |
startMonitoring(url) | |
} | |
} | |
func stopMonitoring() { | |
// Stop listening for changes to the directory, if the source has been created. | |
if directoryMonitorSource != nil { | |
// Stop monitoring the directory via the source. | |
directoryMonitorSource?.cancel() | |
url = nil | |
} | |
} | |
func getMonitoringURL() -> String { | |
return self.url?.absoluteString ?? "NO URL MONITORED" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a partially modified macOS directory monitor published by Apple during WWDC 2016.
You can find original Apple version at: Original Apple DirectoryMonitor
Original version cannot smootly stop and restart monitoring on a different directory. I've tested my modified version it and it's working. Feel free to contact me here if you have suggestions.