Swift / Cocoa: 如何监视文件夹的变化?

20

我正在编写一个小型的macOS应用程序,想要监视一个文件夹是否发生更改。它不需要监视子文件夹,只需在文件夹中添加或删除文件时接收通知。

看起来可以使用NSFileCoordinator和/或NSFilePresenter来实现这一点,但我无法理解如何使用它们来实现这一点。

理想情况下,这可以在不必包含第三方框架的情况下解决。

2个回答

20

您可以使用NSFilePresenter来实现这一点。 观察类必须符合以下NSFilePresenter的规范。

presentedItemURL将指向您想要观察的文件夹。 如果文件夹中发生更改,将会调用presentedSubitemDidChangeAtURL。下面的代码片段可以给您一个思路如何实现它。

class ObservingClass: NSObject, NSFilePresenter {

    lazy var presentedItemOperationQueue = NSOperationQueue.mainQueue()
    var presentedItemURL:NSURL?
    

    func presentedSubitemDidChangeAtURL(url: NSURL) {
        let pathExtension = url.pathExtension    
        if pathExtension == "png"{
            refreshImages()
        }
    }

   func refreshImages(){
        let path = snapshotPath
        var isDirectory: ObjCBool = ObjCBool(false)
        
        if NSFileManager.defaultManager().fileExistsAtPath(path!, isDirectory: &isDirectory){
            if isDirectory{
                do {
                    let list = try NSFileManager.defaultManager().contentsOfDirectoryAtPath(path!) as Array<String>
                    for filePath in list {
                        if filePath.hasSuffix(".png"){
                            if let snapshot = snapshotAtPath(path! + "/" + filePath){
                                newSnapshotArray += [snapshot]
                            }
                        }
                    }
                } catch {
                    // error handling 
                }
            }
        }
    }
}

最好的祝愿。


谢谢。这太完美了。 :) 我试过了,它的效果非常好。但是有一个问题。我也尝试使用presentedSubitemDidAppear(at:),而不是presentedSubitemDidChangeAtURL(),因为我只对添加到文件夹中的项目感兴趣。但是这个方法从来没有被调用过。只有didChange。你知道为什么吗? - eivindml
2
我在NSFilePresenter方面进行了很多实验,并得到了相同的经验,即presentedSubitemDidAppear(at:)从未被调用。也许这与苹果在Finder中使用的NSFileCoordinator实现有关。还要注意,在某些情况下,presentedSubitemDidChangeAtURL会被多次调用(例如,复制捆绑包、文件重命名等)。 - Marc T.
感谢您的输入。有点奇怪它不起作用,但我会使用presentedSubitemDidChangeAtURL()让它工作,只需要做更多的检查和处理。 - eivindml
@eivindml 这是一个自 2013 年以来可能永远不会被修复的错误。presentedSubitemDidAppearaccommodatePresentedSubitemDeletion 永远不会被调用。例如,请参见 https://dev59.com/K2ct5IYBdhLWcg3wD5SU#19343784 - fishinear
谢谢。也许有一天我会提交额外的错误报告。 - eivindml

8

马克 T 的回答仍然有效,并且似乎是最简单的解决方案。

为了使其工作,我需要添加以下行(可以在 ObservingClass 的 init() 中):

NSFileCoordinator.addFilePresenter(self)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接