Created
March 11, 2019 14:22
-
-
Save wildthink/b0ee9dab6399996b2971bd53025d0612 to your computer and use it in GitHub Desktop.
Monitor updates to files is iOS and OSX
This file contains hidden or 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
import Foundation | |
// thanks to https://www.swiftbysundell.com/posts/a-deep-dive-into-grand-central-dispatch-in-swift | |
/// The FileObjserver watches a single File URL but only if the file exists | |
/// If the file is removed, you will get a delete event but nothing else | |
/// thereafter, even if the file is recreated at the same path | |
public class FileObserver { | |
public typealias Event = DispatchSource.FileSystemEvent | |
public let url: URL | |
public var currentEvent: Event { | |
return Event(rawValue: (source?.data ?? 0)) | |
} | |
private let queue: DispatchQueue | |
private var source: DispatchSourceFileSystemObject? | |
public convenience init?(_ file: String) { | |
self.init(URL(fileURLWithPath: file)) | |
} | |
public init?(_ url: URL) { | |
self.url = url | |
guard (try? self.url.checkResourceIsReachable()) ?? false else { return nil } | |
self.queue = DispatchQueue(label: "app.file_observer") | |
} | |
deinit { | |
source?.cancel() | |
} | |
public func start(mask: Event? = nil, closure: @escaping (FileObserver) -> Void) { | |
let mask = mask ?? .all | |
let fd = open(url.path, O_EVTONLY) | |
let source = DispatchSource | |
.makeFileSystemObjectSource(fileDescriptor: fd, eventMask: mask, queue: queue) | |
source.setEventHandler { [weak self] in | |
guard let this = self else { return } | |
closure(this) | |
} | |
self.source = source | |
source.resume() | |
} | |
} | |
extension DispatchSource.FileSystemEvent { | |
public var name: String { | |
switch self { | |
case .all: return "all" | |
case .attrib: return "attrib" | |
case .delete: return "delete" | |
case .extend: return "extend" | |
case .funlock: return "funlock" | |
case .link: return "link" | |
case .rename: return "rename" | |
case .revoke: return "revoke" | |
case .write: return "write" | |
default: | |
return "<fsevent: \(rawValue)>" | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment