When to delete files in NSTemporaryDirectory - objective-c

I am building a multitasking application which includes a functionality for viewing large pdf files. In order to avoid downloading the file each time the user wants to view the file, i download the file in the NSTemporaryDirectory and use the UIDocumentInteractionController to provide "Quick Look" and "Open in iBooks".
I wish to clear all temporary files when the user exits the application in order to avoid consuming space on user's device. Since my application is multitasking and my applicationWillTerminate method never gets called, the files are never deleted. When is it best to clear the NSTemporaryDirectory and how can i do it? Am i missing something?
Thanks in advance

You can make use of an old UNIX trick that also works fine on iOS (I know since I make use of it):
Save the files.
Open them.
Remember the filedescriptors.
Delete the files (this is the magic part).
The effect is that the files remain open as long as you don't close them. But their directory entries are gone, i.e. the files won't show up in a directory listing any more. The cool thing is now that as soon as you close one of those filedescriptors the corresponding file automatically gets completely deleted from disk. It doesn't matter whether you explicitly call close on them or whether your app terminates or crashes, in all those cases the files get deleted by the OS and you don't need to worry about it.
The downside is that you need to change your code so that it can work with the filedescriptors as you cannot access the files by name any longer.

applicationWillResignActive
in your Appdelegate is the best place to do.

Related

Uploading files to server via JSF 2.2 and h:inputFile

UPDATE:
It turns out that there was an ajax call inside the inputFile that would cause the upload to start prematurely. That ajax was supposed to handle the selected file before the actual submit button was clicked, but neither I nor the person who coded it before me knew it would behave that way. And, as we only tested it either locally or with small files, we never noticed the problem.
I'm a newbie when it comes to file upload and I need some guidance on that subject.
I have a code that gets a file through h:inputFile then, when the submit button is pressed, sends it to the server using InputStream and OutputStream in a pretty standard way. It works well, but I'm facing a problem:
When I select the file, it takes its time to upload to the page(?). Then, when I click the submit button, it takes its time again to send that file to the server.
To make myself clear, here's a real case: I clicked the inputFile button and selected a 50mb file. It took 10min to conclude that. Then, I clicked the submit button and it took another 10min to send it to the server. That's a total 20min to upload that file, when it should have been only 10min.
Saving that time is crucial for my users, since their internet is very slow (< 1mbps) and they will be uploading videos around 40-90mb, which will take hours.
So, how do I optimize that? And, as I'm already asking, how exactly does h:inputFile work - I mean, it sets the Part in the bean, which can then be handled, but does it actually upload the file right away?
I'm using JSF 2.2.7 and GlassFish 4.
(Sorry that I didn't post the code, but I don't really think it's necessary. If that's not the case, just let me know.)

Sandbox and Saving files

I know about Sandbox limitations and and my usual technique of having the user save a file is via the NSSavePanel, which automagically grants the app the necessary priviliges to the location, as indicated by the user.
Now, here's the... not-so-uncommon scenario :
User creates a new file, in my app
Saves is for the first time (so, there's a good reason for the NSSavePanel to show up)
Then edits the contents of the document (please, note that my app is not a typical NSDocument-compliant one)
And finally he want to re-save it. (not "Save (it) as.." but just... "Save (it)" - since he's already specified a location, right?)
How is this doable? What's the "approved" way of achieving that? I've read about bookmarks but a) I'm not sure whether it is what I need, b) I haven't managed to find any real code example.
So, any ideas?
Please, note : no-matter-what, the solution must be fully-functional for 10.6 as well.
UPDATE : Hmm... That's just weird (or at least unexpected). Just tried re-saving at a previous location already selected via NSSavePanel and it seems to be working (without doing anything). Is that possible? (And yep, just re-checked it twice : the app is sandboxed)
You provided your own answer - “which automagically grants the app the necessary priviliges to the location, as indicated by the user” - when the user selects the file in the file panel the sandbox is extended to include the selected location and for the rest of the current execution your app my access it.

Register Double-Click on Desktop (but not on Icons !)

Here's a though question:
I need to find out when the user double-clicked the OS X desktop, but not icons on it.
Now, I have thought of the following solutions, though I am not sure if they are doable:
Using desktop icons position (not sure how to get them), and the size of the desktop icons, we could theoretically check once the user double-clicks on the desktop, if it is inside one of the icon areas. Contra: Might not be flawless as some icons might be transparent or not taking up the entire icon size.
Maybe there is a variable that tells us if a icon from the desktop has been clicked? Then we could just check if that variable has been activated when the user double-clicked the last time the desk.
I am certainly still open to other (better) solutions, but they need to be sandboxable for the Mac App Store.
This is probably not going to be appropriate for the Mac App Store, for a number of reasons.
First, how are you going to intercept clicks outside your window? There are a few different mechanisms for this (e.g., event taps), but none of them are allowed in sandboxed apps. And that's intentional, and for a good reason—you're not supposed to be interfering with other apps or with the OS.
On top of that, it's hard to imagine that whatever you're trying to do wouldn't count as non-standard UI/HIG stuff, which is another reason for rejection.
But, assuming none of that were a problem, and you could intercept clicks on the desktop, there's no documented way to get all the icons on the desktop, so you have to read the .DS_store file directly, which means relying on private implementation information, which is another thing you're not allowed to do.
Finally, you have to get access to that .DS_store file. Unless you're expecting the user to drag the (invisible) file or its parent directory to your app or select it in an NSOpenPanel or something, the only way to get such access from inside the sandbox is via a temporary exception entitlement. Which you can't use unless you can justify to the reviewer why you need it as a workaround for a bug or limitation in the OS. So, what's your justification going to be?

Mac Sandboxed App Loses File Permissions to Other Apps

I'm developing an app that is currently sandboxed. It acts as a basic text editor. Recently, I wanted to test what happens when I open a file in my app and another app at the same time, make an update in one app, then then see the updated in the other. I'm using Coda or BBEdit as my alternative editors. If I turn off sandboxing -- then this issue does not exist. However, since apps are required to be sandboxed as of March 1, I would rather implement a solution rather than wait and see.
When I open both files and make an edit in my app and then switch to the other app, the changes are reflected so that those editors have the version just saved from my app. However, if I perform the converse of saving from their app and then moving to mine -- no joy. Without performing any action, the console reports two specific errors: deny file-issue-extension and deny file-write-data. The app appears to be losing privileges to edit the document since it was changed by an external editor after the document was opened in my app. If I try to save the file in my app, it asks to duplicate the document because it has lost access to the original document. This doesn't happen the other way around because those apps have not been sandboxed and therefor have permissions that my app does not. It also doesn't appear that you can prevent the other app from making the changes if you don't want this behavior.
The documentation on developer.apple.com mentions nothing of this type of situation. I am not sure if this is intended behavior. If it is, then I can just tell my user that the document permissions have been lost and they should either save a new version or re-open the file. If it is NOT intended behavior, then what method in the NSDocument API would grant permission to the file once it has been lost? I'm assuming the answer is the former, that this is intended, but can anyone confirm and is there documentation?
Without performing any action, the console reports two specific errors: deny file-issue-extension and deny file-write-data. The app appears to be losing privileges to edit the document since it was changed by an external editor after the document was opened in my app. If I try to save the file in my app, it asks to duplicate the document because it has lost access to the original document
The correct behavior in a situation like this is to not overwrite the file, but to prompt the user if they want to reload the document, if so reload it and then write it.
The OS is doing the right thing by not allowing a blind write over a file that has changed.
See NSFilePresenter - (void)presentedItemDidChange to see if it changed. Reread the file and then see if you can save it. You dont say you have been denied a read on the file.
Also, since you havent posted any code it might be helpful to show what code you are using to access the file and to save it. NSDocument has built in handling for some types of file changes in the sandbox.
Lets call your App ScottEdit and your competitor as StackEdit
There could be several things going on. NSDocument has a lockDocument method. StackEdit may have locked the document and did NOT unlock it after save. If you quit the app, the file should be unlocked and available for your app. If this is the case, you will need to create a notification for when the file attributes change using kqueue or another.
If the other app is "blocking" access to your app. You can send an email to that developer and ask him to update his app so it unlocks the document after save. This last step is in addition to setting up notifications because another developer may come along and do the same thing (breaking your app).

Dragging Files on the Dock Icon

I know how handle dragging of files on the dock icon, and it has been asked before.
However, I'm wondering, can I somehow get more control?
For example, can I make the dock icon reject files that are not in the user's folder and allow only files that are in the user's folder?
I'd rather do that instead of the app appearing as if it handles files outside the user's folder, and then within the app delegate afterwards reject the files by detecting the file paths. That doesn't seem good from a user's perspective.
I realized that my question is kind of meaningless, as Option-dropping files on the dock icons forces the operation to be allowed, in any case. So there is simply no getting around handling the thing after the drop operation has been allowed. Thus, ignore this question :)