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