Поставщик файлов iOS 11 - рабочий набор никогда не перечисляется - PullRequest
0 голосов
/ 04 сентября 2018

В настоящее время я работаю над расширением провайдера файлов iOS 11, чтобы перечислять файлы, удаленно хранимые нашей службой. До сих пор мне удавалось просматривать мою кэшированную базу данных файлов, а также перечисления моего элемента в облаке.

Мой следующий шаг - создание рабочего набора, но до сих пор я не добился успеха при перечислении системы с моим перечислителем рабочего набора. Перечислитель создается, но никогда не перечисляется, перечисляет ли он элементы или изменения.

Я работаю с локальной базой данных для своих предметов, отслеживаю lastUsedDate, tagData и favoriteRank. Они еще не синхронизируются между устройствами, но это не должно помешать локальному устройству отображать эти элементы. Каждый раз, когда мое хост-приложение отображает файл, оно устанавливает его lastUsedDate и вызывает signalEnumerator(for: myItemIdentifier) и signalEnumerator(for: .workingSet).

Мой подкласс NSFileProviderExtension также реализует setTagData(...), setFavoriteRank(...) и setLastUsedDate(...).

У меня есть специальный класс для перечисления через рабочий набор следующим образом:

class WorkingSetEnumerator: NSObject, NSFileProviderEnumerator {
    let items: [NSFileProviderItem]
    // Initialise with the workings set items, might not be correct but should work as first step
    init(items: [NSFileProviderItem]) { 
        self.items = items
        super.init()
    }

    func invalidate() {
        // Empty since it is a "dummy" implementation
    }

    func enumerateItems(for observer: NSFileProviderEnumerationObserver, startingPage page: NSFileProviderPage) {
        observer.didEnumerate(self.items)
        observer.finishEnumerating(upTo: nil)
    }

    func enumerateChanges(for observer: NSFileProviderChangesObserver, from anchor: NSFileProviderSyncAnchor) {
         //TODO: Implement!
         fatalError("Not Implemented, yet!")
    }
}

Ничего особенного здесь нет. Здесь для примера он инициализирован с фиктивными данными, но я также пытался использовать живые данные и та же проблема.

Функция, запрашивающая перечислитель, реализована следующим образом: Переопределить перечислитель функции (для containerItemIdentifier: NSFileProviderItemIdentifier) ​​throws -> NSFileProviderEnumerator {

    if containerItemIdentifier == .rootDirectory {
        // return a folder enumerator on the root
    } else if containerItemIdentifier == .workingSet {
        let items = [DummyItem()]
        return WorkingSetEnumerator(items: items)
    } else {
        // return Folder or File enumerator based on the item
    }
}

Вот реализация моего DummyItem:

class DummyFileItem: NSObject, NSFileProviderItem {
    var parentItemIdentifier: NSFileProviderItemIdentifier {
        return NSFileProviderItemIdentifier.rootContainer
    }

    var itemIdentifier: NSFileProviderItemIdentifier {
        return NSFileProviderItemIdentifier("Dummy")
    }

    var filename: String {
        return "Dummy"
    }

    var typeIdentifier: String {
        return "public.folder"
    }

    var isShared: Bool {
        return true
    }

    var isTrashed: Bool {
        return false
    }

    var lastUsedDate: Date? {
        return Date()
    }

    var favoriteRank: NSNumber? {
        return NSNumber(value: NSFileProviderFavoriteRankUnranked)
    }

    var tagData: Data? {
        return nil
    }

    var documentSize: NSNumber? {
        return NSNumber(value: 0)
    }

    var childItemCount: NSNumber? {
        return NSNumber(value: 0)
    }

    var isDownloading: Bool {
        return false
    }

    var isDownloaded: Bool {
        return true
    }

    var downloadingError: Error? {
        return nil
    }

    var isUploaded: Bool {
        return true
    }

    var isUploading: Bool {
        return false
    }

    var uploadingError: Error? {
        return nil
    }

    var isMostRecentVersionDownloaded: Bool {
        return true
    }

    var isSharedByCurrentUser: Bool {
        return true
    }
}

Просто некоторые фиктивные данные, которые должны отображать мой элемент хотя бы на последней вкладке.

Как описано ранее, я также попробовал это с моими локальными элементами, которые содержат реальные данные, и то же самое происходит, перечислитель создается, но не перечисляется.

Есть ли способ принудительно перечислить рабочий набор? Любая идея основана на моем описании того, что может отсутствовать?

Спасибо за ваше время и помощь.

1 Ответ

0 голосов
/ 06 сентября 2018

Мне удалось заставить его работать, благодаря этому ответу на форуме Apple: https://forums.developer.apple.com/thread/100172?q=iOS11%20File%20Provider%20working%20set.

Чего не хватало, это NSFileProviderSyncAnchor для рабочего набора. Для моих фиктивных данных привязка синхронизации предоставляет только Int64, жестко закодированный в 0, и рабочий набор теперь перечисляется один раз, что достаточно для моего фиктивного примера.

Теперь, чтобы заставить его работать с моими фактическими данными, мне нужно будет правильно отслеживать его каждый раз, когда я делаю изменения в файлах, принадлежащих рабочему набору, и сигнализирую об изменениях в рабочем наборе. '

Надеюсь, это кому-нибудь поможет, так как это не тривиально и не очень хорошо задокументировано.

...