【问题标题】:iOS 11 File Provider - The working set is never enumeratediOS 11 文件提供程序 - 从不枚举工作集
【发布时间】:2018-09-04 12:47:31
【问题描述】:

我目前正在开发 iOS 11 文件提供程序扩展,以枚举我们的服务远程存储的文件。 到目前为止,我已经能够浏览缓存的文件数据库,以及我的项目的云枚举。

我的下一步是创建工作集,但到目前为止,我还没有发现让系统使用我的工作集枚举器进行枚举的任何成功。枚举器已创建,但从不枚举,无论是枚举项目还是更改。

我为我的项目使用本地数据库,跟踪 lastUsedDatetagDatafavoriteRank。它们尚未跨设备同步,但这不应阻止本地设备显示这些项目。 每次我的宿主应用程序显示文件时,它都会设置其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!")
    }
}

这里没什么特别的。为了举例,这里使用虚拟数据进行初始化,但我也尝试使用实时数据和相同的问题。

请求枚举器的函数实现如下: 覆盖 func enumerator(for 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
    }
}

只是一些虚拟数据,至少应该在最近的标签中显示我的项目。

如前所述,我也尝试使用包含真实数据的本地项目,同样的情况是,创建了枚举器但未枚举。

有没有办法强制枚举工作集?根据我对可能缺少的内容的描述有什么想法吗?

感谢您的时间和帮助。

【问题讨论】:

    标签: ios ios11 fileprovider-extension


    【解决方案1】:

    感谢 Apple 论坛上的这个答案:https://forums.developer.apple.com/thread/100172?q=iOS11%20File%20Provider%20working%20set,我设法让它工作。

    缺少的是工作集的NSFileProviderSyncAnchor。对于我的虚拟数据,同步锚只提供了一个硬编码为 0 的 Int64,并且工作集现在被枚举一次,这对于我的虚拟示例来说已经足够了。

    现在要让它在我的实际数据上工作,我需要在每次对属于工作集的文件进行更改时正确跟踪它,并向工作集发出更改信号。'

    希望这会对某人有所帮助,因为这不是微不足道的,也不是很好的记录。

    【讨论】:

    • 您好!你能描述一下如何正确碰撞 NSFileProviderSyncAnchor 吗?我只能看到我在第一次调用enumerateItems(for observer: 时枚举的虚拟项目,而其他调用在文件 UI 中不可见。我使用NSFileProviderSyncAnchor(rawValue:NSKeyedArchiver.archivedData(withRootObject: NSNumber(value: 0))) 作为起始锚点,然后在startProvideItem 方法中加载每个文件时将值增加1。
    • 您是否在工作集枚举器中覆盖了currentSyncAnchor(completionHandler:)?也许这会有所帮助。每次同步锚点发生碰撞后,您还会致电NSFileProviderManager.default.signalEnumerator(.workingSet ...) 吗?希望对您有所帮助,如果没有,您可以添加更多细节吗?请注意,任何东西都可以用作NSFileProviderSyncAnchor,因为它代表一个 500 字节的 blob。文档本身提供了一个使用 Date 作为同步锚点的示例,实际上在虚拟示例的上下文中可能更容易管理。
    • 谢谢,我认为问题出在 FileProviderItem 中的 parentId 上。我将真实的 parentId 映射到所有项目的根容器,并在最近的 UI 中正确显示。另外,我使用日期作为同步锚而不是 int。
    猜你喜欢
    • 2022-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 1970-01-01
    • 2022-10-25
    • 2017-05-03
    相关资源
    最近更新 更多