Swift / Cocoa:如何观察文件夹的变化?

Posted

技术标签:

【中文标题】Swift / Cocoa:如何观察文件夹的变化?【英文标题】:Swift / Cocoa: How to watch folder for changes? 【发布时间】:2018-05-20 21:43:46 【问题描述】:

我正在编写一个小型 macOS 应用程序,我希望能够在其中查看文件夹的更改。它不需要监视子文件夹,我只想在文件被添加到文件夹或被删除时收到通知。

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

理想情况下,无需包含第三方框架即可解决此问题。

【问题讨论】:

【参考方案1】:

您可以使用 NSFilePresenter 执行此操作。 观察类必须符合如下所示的 NSFilePresenter。

presentedItemURL 将指向您要观察的文件夹。 如果显示的文件夹发生更改,则调用SubitemDidChangeAtURL。下面截取的代码可以让您了解它是如何工作的。

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。你知道为什么吗? 我对 NSFilePresenter 进行了很多实验,得到了与从未调用过presentSubitemDidAppear(at:) 相同的体验。也许它与 Apple 对 Finder 的 NSFileCoordinator 实现有关。另请注意,在某些情况下,presentSubitemDidChangeAtURL 会被多次调用(例如,复制包、文件重命名......)。 感谢您的意见。它不起作用有点奇怪,但我会让它与 presentedSubitemDidChangeAtURL() 一起工作,只需要做更多的检查和工作。 @eivindml 这是一个至少从 2013 年开始的错误,可能永远不会被修复。 presentedSubitemDidAppearaccommodatePresentedSubitemDeletion 永远不会被调用。参见例如***.com/a/19343784/908621 谢谢。也许有一天我会提交一份额外的错误报告。【参考方案2】:

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

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

NSFileCoordinator.addFilePresenter(self)

【讨论】:

以上是关于Swift / Cocoa:如何观察文件夹的变化?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Swift 为 Cocoa 应用程序中的 NSLider 值更改设置动画

《从零开始学Swift》学习笔记(Day 66)——Cocoa Touch设计模式及应用之通知机制

《从零开始学Swift》学习笔记(Day 66)——Cocoa Touch设计模式及应用之通知机制

Cocoa/Swift:遍历路径中文件夹的名称

如何将用 Swift 编写的 Cocoa Touch 框架导入 .pch 文件?

Swift互用性:采用Cocoa设计模式(Swift 2.0版)-b