Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2016
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.10 KB | None | 0 0
  1. /*
  2. Copyright (C) 2016 Apple Inc. All Rights Reserved.
  3. See LICENSE.txt for this sample’s licensing information
  4.  
  5. Abstract:
  6. `DirectoryMonitor` is used to monitor the contents of the provided directory by using a GCD dispatch source.
  7. */
  8.  
  9. import Foundation
  10.  
  11. /// A protocol that allows delegates of `DirectoryMonitor` to respond to changes in a directory.
  12. protocol DirectoryMonitorDelegate: class {
  13. func directoryMonitorDidObserveChange(_ directoryMonitor: DirectoryMonitor)
  14. }
  15.  
  16. class DirectoryMonitor {
  17. // MARK: Properties
  18.  
  19. /// The `DirectoryMonitor`'s delegate who is responsible for responding to `DirectoryMonitor` updates.
  20. weak var delegate: DirectoryMonitorDelegate?
  21.  
  22. /// A file descriptor for the monitored directory.
  23. var monitoredDirectoryFileDescriptor: CInt = -1
  24.  
  25. /// A dispatch queue used for sending file changes in the directory.
  26. let directoryMonitorQueue = DispatchQueue(label: "com.example.apple-samplecode.lister.directorymonitor", attributes: .concurrent)
  27.  
  28. /// A dispatch source to monitor a file descriptor created from the directory.
  29. var directoryMonitorSource: DispatchSourceFileSystemObject?
  30.  
  31. /// URL for the directory being monitored.
  32. var url: URL
  33.  
  34. // MARK: Initializers
  35. init(URL: URL) {
  36. self.url = URL
  37. }
  38.  
  39. // MARK: Monitoring
  40.  
  41. func startMonitoring() {
  42. // Listen for changes to the directory (if we are not already).
  43. if directoryMonitorSource == nil && monitoredDirectoryFileDescriptor == -1 {
  44. // Open the directory referenced by URL for monitoring only.
  45. monitoredDirectoryFileDescriptor = open(url.path, O_EVTONLY)
  46.  
  47. // Define a dispatch source monitoring the directory for additions, deletions, and renamings.
  48. directoryMonitorSource = DispatchSource.makeFileSystemObjectSource(fileDescriptor: monitoredDirectoryFileDescriptor, eventMask: [.write, .delete], queue: directoryMonitorQueue)
  49.  
  50. // Define the block to call when a file change is detected.
  51. directoryMonitorSource?.setEventHandler(handler: {
  52. // Call out to the `DirectoryMonitorDelegate` so that it can react appropriately to the change.
  53. self.delegate?.directoryMonitorDidObserveChange(self)
  54. })
  55.  
  56. // Define a cancel handler to ensure the directory is closed when the source is cancelled.
  57. directoryMonitorSource?.setCancelHandler(handler: {
  58. close(self.monitoredDirectoryFileDescriptor)
  59.  
  60. self.monitoredDirectoryFileDescriptor = -1
  61.  
  62. self.directoryMonitorSource = nil
  63. })
  64.  
  65. // Start monitoring the directory via the source.
  66. directoryMonitorSource?.resume()
  67. }
  68. }
  69.  
  70. func stopMonitoring() {
  71. // Stop listening for changes to the directory, if the source has been created.
  72. if directoryMonitorSource != nil {
  73. // Stop monitoring the directory via the source.
  74. directoryMonitorSource?.cancel()
  75. }
  76. }
  77. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement