iCloud NSMetadataQuery和更新(NSMetadataQueryUpdateChangedItemsKey)

时间:2015-08-24 08:57:16

标签: ios icloud nsmetadataquery

我正在使用NSMetaDataQuery监控我的iCloud沙箱(iOS) - 并且一切正常。

我尝试使用NSMetadataQueryUpdateChangedItemsKey中的NSMetadataQueryDidUpdateNotification来有效地更新文件系统的内部模型。我遇到的挑战是,当移动/重命名文件时,我怎么知道原始文件路径 - 所以我可以更新我的模型?

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

任何人都知道应该如何完成(或者如果NSMetaDataItem对象在NSMetaDataQuery的生命周期中持续存在的情况实际上是这样 - 并且保持'附加到同一文件系统项目。)

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

我使用并排运行的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)
    }
})