iCloud NSMetadataQuery and updates (NSMetadataQueryUpdateCha



我正在使用NSMetaDataQuery监控我的iCloud沙盒(iOS) -并且一切都运行良好。

我试图在NSMetadataQueryDidUpdateNotification中使用NSMetadataQueryUpdateChangedItemsKey,以便有效地更新我的文件系统的内部模型。我所面临的挑战是,当文件被移动/重命名时,我如何知道原始文件路径-以便我可以更新我的模型?

看来,NSMetaDataItem对象是持久的(即相同的对象实例更新时,路径改变),所以我可以使用指针值作为一种索引到我的模型。然而,我将利用一个明显的实现细节(这可能会改变)。也许NSMetaDataItems在内存不足时被回收?

有谁知道这个应该怎么做(或者如果实际上是NSMetaDataItem对象在NSMetaDataQuery的生命周期内持续存在-并且保持'附加'到相同的文件系统项。)

是的,NSMetadataQuery不提供查询前一个路径的方法。

当一个项被移动时,它在NSMetadataQuery结果中的索引保持不变。因此,我们可以复制结果的路径,当更新开始时,我们只需要在复制数组的确切位置检查NSMetadataItem。

    if let updatedObj = obj.userInfo?[NSMetadataQueryUpdateChangedItemsKey] as! [NSMetadataItem]? {
        for it in updatedObj {
            let url = it.valueForAttribute(NSMetadataItemURLKey) as! NSURL
            let value = it.valueForAttribute(NSMetadataUbiquitousItemIsUploadedKey) as! NSNumber
            print("Path: " + url.path!)
            print("Updated: " + value.stringValue)
            let index = metaDataQuery.indexOfResult(it)
            let prevPath = duplicatedPathArray[index]
            if (prevPath != url.path!) {
                print("File Moved. Previous path: " + prevPath)
                duplicatePath()
            }
        }
    }

确保每次添加或删除文件时更新数组

文档提到结果适合Cocoa绑定,这意味着这些对象很可能是持久的。

我使用NSFilePresenterNSMetadataQuery并排运行的更硬核组合来监视容器中的文档。NSFilePresenter有方便的API来检测文件何时被移动:

func presentedSubitem(at oldURL: URL, didMoveTo newURL: URL)

当你在容器中移动文件时,你必须明确地通知文件协调器你正在移动文件(参见第1-3点):

let fc = NSFileCoordinator()
var error: NSError?
fc.coordinate(writingItemAt: from, options: .forMoving, writingItemAt: to, options: .forReplacing, error: &error, byAccessor: {
    (fromURL, toURL) in
    do {
        // 1
        fc.item(at: fromURL, willMoveTo: toURL)
        try FileManager.default.moveItem(at: fromURL, to: toURL)
        // 2
        fc.item(at: fromURL, didMoveTo: toURL)
    } catch {
        // 3
        fc.item(at: fromURL, didMoveTo: fromURL)
    }
})

最新更新