iCloud NSMetadataQuery и обновления (NSMetadataQueryUpdateChangedItemsKey)

Я наблюдаю за своей песочницей iCloud (iOS), используя NSMetaDataQuery рекомендуются - и все работает хорошо.

Я пытаюсь использовать NSMetadataQueryUpdateChangedItemsKey в NSMetadataQueryDidUpdateNotification для того, чтобы эффективно обновить мою внутреннюю модель файловой системы. У меня есть проблема в том, что когда файл перемещается / переименовывается, как я могу узнать исходный путь к файлу - чтобы я мог обновить свою модель?

Похоже, что NSMetaDataItem объекты являются постоянными (т. е. один и тот же экземпляр объекта обновляется при изменении пути), поэтому я могу использовать значение указателя в качестве своего рода индекса в моей модели. Однако - я бы воспользовался очевидной деталью реализации (которая может измениться). Возможно, NSMetaDataItems перерабатываются при нехватке памяти?

Кто-нибудь знает, как это должно быть сделано (или, если это действительно так, NSMetaDataItem объекты сохраняются в течение всей жизни NSMetaDataQuery - и оставайтесь "привязанными" к тому же элементу файловой системы.)

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()
            }
        }
    }

Обязательно обновляйте массив каждый раз, когда файл добавляется или удаляется.

В документации упоминается, что результаты подходят для привязок какао, что означает, что, скорее всего, эти объекты являются постоянными.

Я использую более хардкорную комбинацию NSFilePresenter а также NSMetadataQuery работает рядом, чтобы контролировать документы в контейнере. 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)
    }
})
Другие вопросы по тегам