3

我正在监视我的 iCloud 沙盒 (iOS) NSMetaDataQuery,建议使用 - 一切运行良好。

我正在尝试使用NSMetadataQueryUpdateChangedItemsKeyinNSMetadataQueryDidUpdateNotification来有效地更新文件系统的内部模型。我面临的挑战是,当文件被移动/重命名时,我怎么知道原始文件路径——所以我可以更新我的模型?

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

任何人都知道应该如何做到这一点(或者如果实际上是NSMetaDataItem对象在生命周期内持续存在NSMetaDataQuery- 并保持“附加”到同一个文件系统项。)

4

2 回答 2

2

是的,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()
            }
        }
    }

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

于 2016-09-01T09:14:42.533 回答
0

文档提到结果适用于 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)
    }
})
于 2016-11-27T21:22:35.960 回答