管理iOS应用中的Documents/Inbox文件夹的好方法

her*_*ube 12 ios

当文档交互系统将文件传递到iOS应用程序时,该文件的副本将存储在应用程序包的Documents/Inbox文件夹中.应用程序处理完文件后,显然需要从中删除文件Documents/Inbox,否则文件夹将继续增长并浪费存储在设备上.

但是,我对这个简单的解决方案(A)感到不舒服,因为我的应用程序需要在完成处理和删除文件之前与用户进行交互.如果用户在此交互期间暂停应用程序,并且该应用程序在后台处理时会被杀死,则应用程序下次启动时将不会删除过时文件.当然,我可以改进我的应用程序以涵盖这种情况,但我怀疑总会有另一个边框案例会让我留下一个"不干净"的Documents/Inbox文件夹.

因此,优选的解决方案(B)将是Documents/Inbox在适当的时间移除文件夹(例如,当app正常启动时,即不通过文档交互).我仍然对此感到不舒服,因为我将访问一个文件系统路径,其位置未在任何地方正式记录.例如,如果在iOS的未来版本中,文档交互系统不再放置文件,我的应用程序将会中断Document/Inbox.

所以我的问题是:

  1. 你会推荐解决方案A或B吗?
  2. 您是否使用不同的方法,并且可以概述您的应用程序如何管理Document/Inbox?
  3. 最后但同样重要的是:您是否知道一篇涵盖该主题并且我忽略了的官方Apple文档?

her*_*ube 14

由于我问过这个问题,我已经实现了以下解决方案:

  • 我重新设计了我的应用程序,以便它立即处理通过文档交互传递给它的文件,而根本不涉及用户.除非应用程序崩溃,或者在处理文件的过程中被暂停和终止,否则这应该总是让我干净利落Documents/Inbox.
  • 为了覆盖(罕见)崩溃或暂停/终止的情况,我的应用程序Documents/Inbox在正常启动时删除文件夹(即没有文档交互的目的).为实现此目的,Documents/Inbox文件夹路径必须是硬编码的.

以下是解决方案中的想法:

  • 重新设计应用程序
    • 最初,为用户提供如何处理文件的选择似乎是一个好主意 - 毕竟,提供选择会使应用程序更加灵活并为用户提供更多自由,对吧?
    • 然后我意识到我正试图将决定如何处理文档交互的责任转移给用户.所以我咬紧牙关,事先做出了艰难的决定,然后开心地在我的应用程序中实现了一个简单直接的文档交互系统.
    • 事实证明,没有用户交互也意味着应用程序更容易使用,所以这对我作为开发人员和我的应用程序的用户来说都是一个双赢的局面.
  • Documents/Inbox在应用启动期间删除文件夹
    • Documents/Inbox在应用启动期间删除文件夹只是事后的想法,而不是我的应用处理文档交互的重要部分
    • 因此,我非常愿意承担Apple可能在将来某个时候更改收件箱文件夹的文件系统路径的风险.可能发生的最糟糕的事情是我的应用程序将开始累积一些文件,这些文件是崩溃或暂停/终止方案中的残留物.

最后,进一步发展的一些想法:

  • 如果它没有原来有真正的应该是应用如何处理文档的交互方式不止一种,我想补充一个用户的偏好,使得用户不得不做出决定的前期,而应用程序并不需要停止其处理以询问用户的选择.
  • 如果事实证明用户交互在文档交互处理过程中是绝对不可避免的,我会看一下这种方法:1)在允许用户进行交互之前,将文件移动Documents/Inbox到某种"staging"文件夹; 2)让用户进行互动; 3)以"用户选择的任何方式"处理"staging"文件夹中的文件.这里重要的是"staging"文件夹位于已知位置,完全由应用程序管理.如果用户在用户交互步骤中暂停然后终止应用程序,则可以在下次启动应用程序时采取适当的操作.

编辑

在iOS 7中,Documents/Inbox一旦创建它就不再可能删除.该NSFileManager方法removeItemAtPath:error:返回Cocoa错误513,该错误解析为NSFileWriteNoPermissionError(参见此基础常量列表).该错误似乎与POSIX权限无关,但是,它看起来好像系统本身会干扰删除尝试(可能保护应用程序包结构?).

另外值得注意的是,Apple现在明确地Documents/Inbox在该UIApplicationDelegate方法的文档中命名application:openURL:sourceApplication:annotation:.他们也这么说

[...]您的应用有权读取和删除此目录中的文件,但无权写入这些文件.如果要修改文件,则必须先将其移动到其他目录.

关于文档中文件可能加密的内容有很多,但您应该自己阅读.


fis*_*ear 9

随着“文件”应用程序和“就地打开”功能的引入,这个问题变得更加复杂。

如果您没有在您的 中打开“支持就地打开文档”,那么info.plist情况几乎是一样的,从任何其他应用程序打开的文件仍然会出现在目录中Documents/Inbox。但从“文件”应用程序打开的文件会出现在另一个收件箱中,当前位于tmp/<bundle ID of app>-inbox。仍然建议在使用完该文件后将其删除,但不太需要偶尔清理该目录,因为该tmp目录偶尔会被 iOS 清理一次。

如果您确实打开了“支持就地打开文档”,那么情况就会发生巨大变化。从“文件”应用程序和其他一些应用程序打开的文件不再复制到收件箱中,而是在原始位置传递给您。这通常是“文件”应用程序本身内部的某个位置、“文件”应用程序引用的另一个应用程序内部的某个位置,甚至是某个常规 iCloud 位置。如果您公开“文档”文件夹中的文件,那么它甚至可能是您自己的应用程序的文件之一。

不用说,如果你得到这样的文件,一定不要删除它。但是,如果该文件位于收件箱中(这种情况仍然会经常发生),那么您必须将其删除。为了确定这一点,调用的选项application:openURL:options:包含一个UIApplicationOpenURLOptionsOpenInPlaceKey键。如果其值为 ( NSNumber) NO,则该文件位于收件箱中,应将其删除。如果它的值为 YES,则它会就地打开,并且不得删除。

请注意,对于就地打开的文件,您还需要先获得使用它们的权限。startAccessingSecurityScopedResource您可以这样做,但通过和调用来包围对文件的访问stopAccessingSecurityScopedResource。有关详细信息,请参阅Apple 文档。