【问题标题】:What is the best strategy for saving a "Most Recently Used" document list on iOS?在 iOS 上保存“最近使用”文档列表的最佳策略是什么?
【发布时间】:2022-11-10 00:50:01
【问题描述】:

是否有一种万无一失的方法来保存 UIDocument 的 URL,以便应用程序可以在下次启动时继续编辑文档?

我尝试了各种保存 URL 的方法,但有时文档 URL 会与预期的略有不同。

例如,下面的代码:

var scoresURL = FileManager.default.urls(for: .documentDirectory,
                                             in: .userDomainMask).first!

可能会返回这个:

file:///var/mobile/Containers/Data/Application/50E947C1-7A30-40A0-8BB6-1C3BB41A1218/Documents  

但是使用 UIDocumentBrowserViewController 加载的文档可能会将 UIDocument 的 fileURL 路径设置为:

file:///private/var/mobile/Containers/Data/Application/50E947C1-7A30-40A0-8BB6-1C3BB41A1218/Documents  

正是这些细微的差异让我怀疑我是否只是通过维护 MRU 列表做错了事情。

这些问题仅出现在实际设备上。模拟器的路径是稳定的,至少直到模拟器决定重置其状态的任意时间。

【问题讨论】:

  • 根据文档的动态包路径前缀和固定后缀构建路径 - 存储后缀,可能在 UserDefaults 或应用程序容器中
  • 看看这个信息:developer.apple.com/documentation/foundation/userdefaults 尤其是章节:Persisting File References,它讨论了使用 NSURL 书签数据。

标签: ios swift objective-c uidocument uidocumentbrowserviewcontroller


【解决方案1】:

您可以检查哪一个是最后修改的:

var scoresURL = FileManager.default.urls(for: .documentDirectory,
                                             in: .userDomainMask)

let modificationDatesAndURL: (Date, URL) = scoresURL.compactMap { filePathURL in
    let attributes = FileManager.default.attributesOfItem(atPath: urlPath.path)
    if let modificationDate = attributes?[.modificationDate] as? Date {
        return (modificationDate, filePathURL)
    } else {
        return nil
    }
    
}

/// Sort tuples by date
let lastModifiedScoreDateAndURL = modificationDatesAndURL.sorted(by: { $0.0 < $1.0 }).first
let lastModifiedURL = lastModifiedScoreDateAndURL.1

【讨论】:

  • 这是个好主意,但一个问题是该文档甚至可能不在“Doc ents”目录中。除了文件名和/或 URL 之外,我可能还需要存储有关文档所在位置的更多信息。
  • 你可以有一个URL 的扩展名,它指向创建文件的文件夹,是的。
【解决方案2】:

我认为bookmarkData 是您可能正在寻找的。 文档没有说太多,但总体思路是您保留书签数据using this method

func bookmarkData(
    options: URL.BookmarkCreationOptions = [],
    includingResourceValuesForKeys keys: Set<URLResourceKey>? = nil,
    relativeTo url: URL? = nil
) throws -> Data

然后使用this initializer 重新创建 URL:

init(
    resolvingBookmarkData data: Data,
    options: URL.BookmarkResolutionOptions = [],
    relativeTo url: URL? = nil,
    bookmarkDataIsStale: inout Bool
) throws

就我个人而言,我没有遇到任何问题,因为我引用的是目录而不是单个文件,但发现了警示性文章 (like this one) - 引用其结论:

URL书签规则

  • 始终检查书签数据是否过时 (bookmarkDataIsStale)
  • 如果数据过时,更新所有书签数据 - 包括所有可能存储在别处的书签。
  • 小心原子更新 - 需要遵守纪律才能不使用它。
  • 如果需要持久性和原子写入,最好使用其他方法 - 每次保存后更新存储的书签既麻烦又容易出错。

【讨论】:

    猜你喜欢
    • 2014-04-02
    • 1970-01-01
    • 2010-10-25
    • 2010-09-08
    • 2010-09-06
    • 1970-01-01
    • 2011-03-23
    • 2016-11-27
    • 1970-01-01
    相关资源
    最近更新 更多