Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Good way to manage the Documents/Inbox folder in an iOS app

Tags:

ios

When a file is passed into an iOS application by the document interaction system, a copy of the file is stored in the application bundle's Documents/Inbox folder. After the application has processed the file, it obviously needs to remove the file from Documents/Inbox, otherwise the folder will continue to grow and waste storage on the device.

I am uncomfortable with this simple solution (A), however, because my app needs to interact with the user before it can finish processing and removing the file. If the user suspends the app during this interaction period, and the app then gets killed while it is in the background, the stale file will not be removed when the app starts up the next time. Of course I can improve my app to cover this scenario, but I suspect that there will always be another border case that will leave me with an "unclean" Documents/Inbox folder.

A preferrable solution (B) therefore would be to remove the Documents/Inbox folder at an appropriate time (e.g. when the app launches normally, i.e. not via document interaction). I am still uncomfortable with this because I would be accessing a filesystem path whose location is not officially documented anywhere. For instance, my app would break if in a future version of iOS the document interaction system no longer places files in Document/Inbox.

So my questions are:

  1. Would you recommend solution A or B?
  2. Do you use a different approach and can you maybe give an outline of how your app manages Document/Inbox?
  3. Last but not least: Do you know a piece of official Apple documentation that covers the topic and that I have overlooked?
like image 393
herzbube Avatar asked Mar 29 '13 17:03

herzbube


People also ask

How do you organize your documents on iPhone?

Touch and hold the file or folder, then choose an option: Copy, Duplicate, Move, Delete, Rename, or Compress. To modify multiple files or folders at the same time, tap Select, tap your selections, then tap an option at the bottom of the screen.

How do I manage files in iOS?

Manage Your FilesFrom the menu, you can copy, duplicate, move, rename, preview, tag, share or delete the file. To run a command on multiple files, tap the Select link in the upper-right corner on an iPad (the button is hidden behind a three-dot icon on an iPhone). Tap each file you want to include.

Is there a files folder on iPad?

In the Files app, you can find: Files on the iPhone, iPad, or iPod touch that you're using. Files in iCloud Drive, including Pages, Numbers, and Keynote documents. Files in other cloud services and apps, like Box, Dropbox, OneDrive, Adobe Creative Cloud, Google Drive, and more.


2 Answers

Since I have asked this question, I have implemented the following solution:

  • I have redesigned my app so that it now immediately processes a file handed over to it via documentation interaction, without involving the user at all. Unless the app crashes, or is suspended and killed, in the middle of processing the file, this should always leave me with a clean Documents/Inbox.
  • To cover the (rare) case of a crash or suspend/kill, my app removes the Documents/Inbox folder when it is launched normallly (i.e. without the purpose of document interaction). To achieve this the Documents/Inbox folder path is necessarily hardcoded.

Here are the thoughts that went into the solution:

  • Redesigning the app
    • Initially it seemed like a good idea to offer the user a choice how she wanted a file to be processed - after all, offering a choice would make the app more flexible and provide the user with more freedom, right?
    • I then realized that I was trying to shift the responsibility for deciding how document interaction should be handled to the user. So I bit the bullet, made the hard decisions up-front, and then went happily on to implement a simple and straightforward document interaction system in my app.
    • As it turns out, no user interaction also means that the app is easier to use, so here's a win-win situation, both for me as a developer and for the users of my app.
  • Removing Documents/Inbox folder during app launch
    • Removing the Documents/Inbox folder during app launch is just an afterthought, not an essential part of how my app handles document interaction
    • Therefore I am quite willing to take the risk that Apple might change the filesystem path of the inbox folder at some point in the future. The worst thing that can happen is that my app will start to accumulate a few files that are leftovers from crash or suspend/kill scenarios.

And finally, a few thoughts for further development:

  • If it ever turns out that there really should be more than one way how the app can handle document interaction, I would add a user preference so that the user has to make a decision up-front, and the app does not need to stop its processing to ask the user for a choice.
  • If it ever turns out that user interaction is absolutely unavoidable in the middle of the document interaction handling process, I would look at this approach: 1) Before the user is allowed to interact, move the file from Documents/Inbox to some sort of "staging" folder; 2) Let user interaction take place; 3) Process the file in the "staging" folder, in whatever way the user chose. The important thing here is that the "staging" folder is in a known location and is completely managed by the app. Should the user suspend and then kill the app in the middle of the user interaction step, an appropriate action can simply be taken when the app is launched for the next time.

EDIT

In iOS 7 it is no longer possible to remove Documents/Inbox once it has been created. The NSFileManager method removeItemAtPath:error: returns Cocoa error 513 which resolves to NSFileWriteNoPermissionError (cf. this list of Foundation constants). The error does not seem to be related to POSIX permissions, however, it rather looks as if the system itself interferes with the attempt at deletion (possibly protection of the app bundle structure?).

Also noteworthy is that nowadays Apple explicitly names Documents/Inbox in the documentation of the UIApplicationDelegate method application:openURL:sourceApplication:annotation:. They also say that

[...] Your app has permission to read and delete files in this directory but does not have permission to write to them. If you want to modify a file, you must move it to a different directory first.

There is more stuff about possible encryption of the files in the docs, but you should read up on that yourself.

like image 131
herzbube Avatar answered Oct 26 '22 08:10

herzbube


This problem has become much more complicated with the introduction of the Files app, and the "Open in place" feature.

If you do not have "Supports opening documents in place" switched on, in your info.plist, then things are pretty much the same, and files opened from any other app still appear in the Documents/Inbox directory. But files opened from the Files app appear in another inbox, currently at tmp/<bundle ID of app>-inbox. It is still recommended to delete the file once you are done with it, but there is less need to occasionally clean the directory, because the tmp directory gets cleaned by iOS once in a while anyways.

If you do have "Supports opening documents in place" switched on, then things change drastically. Files opened from the Files app and some other apps are no longer copied into an inbox, but they are passed to you at their original location. That is typically some location inside the Files app itself, inside another app referenced from the Files app, or even some general iCloud location. If you expose the files in your Documents folder, then it could even be one of your own app's files.

Needless to say, if you get such a file, you must not delete it. But if the file comes in an inbox, which will still happen a lot as well, then you must delete it. In order to determine this, the options of the application:openURL:options: call contains an UIApplicationOpenURLOptionsOpenInPlaceKey key. If that has value (NSNumber) NO, then the file is in an inbox, and it should be deleted. It it has value YES, then it is opened in-place, and must not be deleted.

Note that for files that are opened in place, you also need to gain permission to use them first. You do that but surrounding the access to the file by startAccessingSecurityScopedResource and stopAccessingSecurityScopedResource calls. See Apple documentation for details.

like image 33
fishinear Avatar answered Oct 26 '22 08:10

fishinear