3

を使用して iCloud サンドボックス (iOS) を監視していNSMetaDataQueryますが、すべて正常に動作しています。

ファイル システムの内部モデルを効率的に更新するためにNSMetadataQueryUpdateChangedItemsKey、を使用しようとしています。NSMetadataQueryDidUpdateNotification私が抱えている課題は、ファイルが移動/名前変更されたときに、元のファイルパスをどのように知ることができるかということです-モデルを更新できますか?

オブジェクトは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 バインディングに適していると記載されています。これは、これらのオブジェクトが永続的である可能性が高いことを意味します。

コンテナー内のドキュメントを監視するために、NSFilePresenterとをよりハードに組み合わせて使用​​しています。ファイルがいつ移動されたかを検出するための便利な API があります。NSMetadataQueryNSFilePresenter

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 に答える