当文档交互系统将文件传递到iOS应用程序时,该文件的副本将存储在应用程序包的Documents/Inbox
文件夹中。在应用程序处理完文件后,显然需要从Documents/Inbox
中删除该文件,否则该文件夹将继续增长并浪费存储在设备上。
我对这个简单的解决方案(A)感到不舒服,因为我的应用程序需要在完成处理和删除文件之前与用户进行交互。如果用户在此交互期间暂停应用程序,并且该应用程序在后台处理时会被杀死,则应用程序下次启动时将不会删除过时文件。当然,我可以改进我的应用程序以涵盖这种情况,但我怀疑总会有另一个边框案例会让我留下一个“不干净的”Documents/Inbox
文件夹。
Documents/Inbox
文件夹(例如,当应用程序正常启动时,即不通过文档交互)。我仍然对此感到不舒服,因为我将访问一个文件系统路径,其位置未在任何地方正式记录。例如,如果在未来版本的iOS中,文档交互系统不再将文件放在Document/Inbox
中,我的应用程序就会中断。
所以我的问题是:
Document/Inbox
吗?答案 0 :(得分:13)
由于我提出了这个问题,我已经实施了以下解决方案:
Documents/Inbox
。Documents/Inbox
文件夹(即没有文档交互的目的)。为实现此目的,Documents/Inbox
文件夹路径必须是硬编码的。以下是解决方案的想法:
Documents/Inbox
文件夹
Documents/Inbox
文件夹只是事后的想法,而不是我的应用处理文档互动的必要部分最后,还有一些进一步发展的想法:
Documents/Inbox
移动文件到某种“staging”文件夹; 2)让用户进行互动; 3)以“用户选择的任何方式”处理“staging”文件夹中的文件。这里重要的是“staging”文件夹是在一个已知的位置,完全由应用程序管理。如果用户在用户交互步骤中暂停然后终止应用程序,则可以在下次启动应用程序时采取适当的操作。修改强>
在iOS 7中,一旦创建Documents/Inbox
,就无法再删除它。 NSFileManager
方法removeItemAtPath:error:
返回Cocoa错误513,该错误解析为NSFileWriteNoPermissionError
(参见this list of Foundation constants)。该错误似乎与POSIX权限无关,但是,它看起来好像系统本身会干扰删除尝试(可能保护应用程序包结构?)。
同样值得注意的是,Apple现在在Documents/Inbox
方法UIApplicationDelegate
的文档中明确指出application:openURL:sourceApplication:annotation:
。他们也说
[...]您的应用有权读取和删除此目录中的文件,但无权写入这些文件。如果要修改文件,则必须先将其移动到其他目录。
the docs中有关于文件可能加密的更多内容,但您应该自己阅读。
答案 1 :(得分:1)
通过引入“文件”应用程序和“就地打开”功能,此问题变得更加复杂。
如果您在info.plist
中未启用“ 不支持打开文档”,则情况几乎相同,并且仍然会显示从其他任何应用程序打开的文件在Documents/Inbox
目录中。但是从“文件”应用打开的文件显示在另一个收件箱中,当前位于tmp/<bundle ID of app>-inbox
。仍然建议您在完成处理后删除该文件,但是偶尔清理目录的需求就更少了,因为tmp
目录有时会被iOS清理一次。
如果这样做已打开“支持在适当位置打开文档”,那么情况将发生巨大变化。从“文件”应用程序和某些其他应用程序打开的文件不再复制到收件箱中,而是在原始位置传递给您。通常是在“文件”应用程序本身内部,在“文件”应用程序引用的另一个应用程序中的某个位置,甚至是一些常规iCloud位置。如果您将文档文件夹中的文件公开,则它甚至可能是您自己应用程序的文件之一。
不用说,如果您得到这样的文件,则一定不能删除它。但是,如果该文件位于收件箱中,而且还会经常发生,那么您必须将其删除。为了确定这一点,application:openURL:options:
调用的选项包含一个UIApplicationOpenURLOptionsOpenInPlaceKey
键。如果该值的值为(NSNumber
否,则该文件位于收件箱中,应将其删除。它的值为YES,然后就地打开它,并且不能删除它。
请注意,对于已打开的文件,还需要获得使用它们的权限。您可以这样做,但是要通过startAccessingSecurityScopedResource
和stopAccessingSecurityScopedResource
调用来访问文件。有关详细信息,请参见Apple documentation。
答案 2 :(得分:0)
我刚才面临同样的问题。和你一样,我没有一个好的解决方案,但是为了回答你的问题,我倾向于选项A而不是选项B,因为我不喜欢可能在操作系统的未来版本中出现问题的想法。因为,在我的情况下,一旦我显示文档的预览就没有用户交互,我可以在收到–documentInteractionControllerDidEndPreview:
委托回调时继续删除它。这是理论上的,因为我还没有对此进行编码,并且暂时不会这样做,因为它是一个低优先级的项目。如果它不起作用或有其他问题,我会在这里报告。我为了查找Apple的文档而输入的Google搜索指向了这个StackOverflow帖子。我还没有看到Apple或其他任何有关此主题的其他有用信息。