Will temporary files be saved by an NSURLSessionUploadTask - ios

I am implementing a resumable upload protocol that uploads in the background on iOS, which means I have to use an NSURLSessionUploadTask with a file. Since it's a resumable upload protocol, the file needs to be truncated based on the data that has already been received by the server, so I need to save a new temporary file to disk that has only the bytes to be uploaded within it.
If I can create that temporary upload file in the tmp/ or /Library/Caches/, can I trust that it will be kept as long as the NSURLSession is running?
EDIT: When an upload fails, the server will be saving the bytes it has already received and communicating that to the client. The client then should only send part of the file, which is why I need to create a smaller temporary file that must not be deleted mid-upload.

Huh? You provide the entire file, and the system takes care of managing the partial upload/download, and notifies you once the transfer is complete. In the case of a download, t hands you a temporary file once the download is complete and you have to save it to a permanent location.
You should not be mucking around with partial files at all.
EDIT:
You don't have access to tmp or /Library/Caches/, except through the sandbox. You can get access to the caches directory with the call
[NSSearchPathForDirectoriesInDomains(
NSCachesDirectory,
NSUserDomainMask, YES) lastObject];
It's my understanding that the caches directory only gets purged on restart, or if the device gets critically low on space, but I seem to remember that the docs are vague on when, exactly, the caches directory gets cleared.
You would probably be better off saving your file to the documents directory, then deleting it once you're done with it.

The answer to your question is no. NSURLSessionUploadTask's description appears to support keeping the source file around but it's misleading:
"In iOS, when you create an upload task for a file in a background session, the system copies that file to a temporary location and streams data from there"
But it says nothing about whether it will keep the original source file in the tmp directory. Specifically for your case where your server supports uploading partial files and you need to restart them after failures. Or in the more common situation where you need to manually restart an entire failed upload, for example from a retry-able server error, or if user killed your app and then restarted it (iOS doesn't continue uploads for user killed apps).
In these cases you can't count on the file still being around if you create it in the apps tmp directory. The file system programming guide tells us this.
https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html
"Use this directory to write temporary files that do not need to persist between launches of your app. Your app should remove files from this directory when they are no longer needed; however, the system may purge this directory when your app is not running. The contents of this directory are not backed up by iTunes or iCloud."
So any tmp directory files can be deleted by iOS when your app stops running, and I can confirm I've seen this in production releases of our app. If you think you may need the source file for the upload again, you must store it in your own app directory, and manage deleting it yourself when done with it. Sorry, extra work, but I don't know of any way around it.

Related

How to prevent automatic file eviction in iCloud Documents?

When I save (either create or update) a small file in the iCloud container of my iOS app, the iCloud daemon first uploads the file to iCloud and then evicts it when the upload is done. If I monitor the file's state using a NSMetadataQuery I can see that after the save, the file's downloading status changes fromNSMetadataUbiquitousItemDownloadingStatusCurrent to NSMetadataUbiquitousItemDownloadingStatusNotDownloaded, and instead of my little test file named test I only see the file .test.icloud instead.
This is bad because if the user goes offline after the file creation, the file cannot be read again. The file should always be available locally after the creation (an outdated file is better than no file).
I know that I can immediately re-download the file using FileManager's method startDownloadingUbiquitousItem after iCloud removes it, but this feels like a silly hack. Is there a way to simply prevent iCloud from evicting the file in the first place?

What is the safest directory in iOS which can be used to download images/pdfs? [duplicate]

Currently i was saving my application data (Media) to the CacheDirectory i.e
/var/mobile/Applications/BEAFC76C-C450-4A3A-9765-A0385A9580F3/Library/Caches
and things were going fine. But recently i got a bug report that the application data has been deleted. When i searched over it, i got this Apple Doc. According to it, DocumentsDirectory should be the ideal place to store the User/Application data.
Put user data in the /Documents/. User data is any
data that cannot be recreated by your app, such as user documents and
other user-generated content.
And Cache should not be used to store the User Data that could not be reproduced by the application.
Put data cache files in the /Library/Caches
directory. Examples of files you should put in this directory include
(but are not limited to) database cache files and downloadable
content, such as that used by magazine, newspaper, and map apps. Your
app should be able to gracefully handle situations where cached data
is deleted by the system to free up disk space.
What should be the ideal place to store it.
EDIT:
I have an application that allows user to store Videos and Photos in the application. For that i used CacheDirectory. But i am getting bug reports that the Data (Videos/Photos) is getting deleted. What conclusion i draw is that the data is being getting delete by the Device itself in order to provide space.
Secondly i also wanna give the iTunes sharing function. So only the particular files has to be stored in the DocumentsDirectory. Some files can never be exposed and some has has to be shared. What should be the ideal way to store the files.
Use Documents (NSDocumentDirectory) for files you wish to share via iTunes.
Use Application Support (NSApplicationSupportDirectory) for files you wish to hide from the user but still be backed up and never deleted by the OS.
Starting iOS 5, Apple says that it's no longer a good thing to save all kind of files in Documents Directory - if you do that, your app will be rejected for sure because this folder is backed up to iTunes & iCloud, unless otherwise specified.
It says that we should save files into Caches or Tmp Directory - these won't be backed up, but it's not a good thing to do because files from these directories can disappear if low memory happens.
So I think the best think to do is to save the important files that you need all the time in your app into Documents Directory and mark them not to be backed up, like this.
Library/Application Support Folder is the folder you should be using.
This directory doesn't always exist, and thus you may need to create it.
You can enable or disable whether you want to backup this data with iTunes or not.
This data is not accessible even if you enable file sharing. Only data that you put in Document directory would be shared with iTunes sharing, so you can still protect your data and get it backed up as well. Apple's documentation

How secure is the iPhone's temporary file directory?

On my app (swift 2.3, xcode 7+, for iOS 9+) I'm write to a file, use the file, and then delete the file from a tmp directory created with NSTemporaryDirectory (on the app sandboxed). Although its a quick automated sequence, for a brief moment the file is written to the tmp directory in order to be used and then deleted.
My concern is: How secure, for that brief moment, is the file stored at tmp directory? Could an attacker get access to the file at the moment it's on the tmp directory?
If you're writing a file just to delete it, you should try to avoid storing the file on the system altogether. If you absolutely have to store the data on the device, you can use the .completeFileProtection option.
According to the documentation, .completeFileProtection will make it so the file is accessible only when the device is unlocked. This means that the only way that someone would have access to your data is if they have your phone's password, are somehow able to remotely unlock it using said password, and then execute code that has access to your app's sandboxed temporary file storage.
As far as I know, this would be very hard to achieve.

Saving file to tmp directory when iphone/ipad storage is full

Let's say an app downloads images from web while the user is browsing the app. Let's assume there are virtually unlimited images and a new image is downloaded whenever the user demands one. These images are saved to tmp directory for caching purpose. Once the user closes the app, all the images downloaded are deleted by the app.
Now, as there are unlimited images, what will happen if the user requests next image, the storage is full and the app attempts to save the image to the tmp directory?
Will the previous images be deleted by the iOS automatically to provide the space required for the new images?
OR
Will the iOS start cleaning tmp directory associated with other apps?(If yes, what happens when the storage is full again and such cleaning has already taken place for all the other apps?)
OR
Will the app crash?
If you try and save a image to disk and the disk is full then NSData's
- (BOOL)writeToURL:(NSURL *)aURL
options:(NSDataWritingOptions)mask
error:(NSError **)errorPtr
Will return NO and an error object will be assigned to the errorPtr passed into the method. This error will have a NSFileWriteOutOfSpaceError. This error is very exceptional, and by the time you get it it's safe to say the system will have already notified the user that he is running out of disk space.
Having said that, a lot can be said about cleaning after yourself. If you're not going to use a saved image resource anymore then delete it from the file-system.
Cheers!
tmp/
Use this directory to write temporary files that do not need to persist between launches of your app. Your app should remove files from this directory when they are no longer needed; however, the system may purge this directory when your app is not running.
The contents of this directory are not backed up by iTunes.
That's the only thing documented. From this I can infer that it won't purge you tmp if your app is running,but it can purge the tmp of other apps which are not running
As #InderKumarRathore says, the docs imply that the system will not delete files from your temp directory when your app is running. The docs also don't promise that the system will delete contents from other apps' temp directories to make space for you.
I would suggest coding defensively: Keep track of the oldest/least recently used files in your temp directory and delete them yourself. Preflight file saves to make sure there is enough space, and display a message to the user if there isn't enough space to save the file(s).

IOS remove downloaded file in app

I developed an Ipad app which download different kind of files, but after a week or some days the downloaded files are removed and the app that open the file can find it anymore.
Could anybody help me, Where should I save downloaded files in my app to avoid that the file came automatically deleted?. IOS usually remove downloaded files after certain time?.
I already read this apple documentation
I know that maybe is not something complicated but I can't figure out why the file is removed If anybody can help me I'll appreciate that.
Put data cache files in the /Library/Caches
directory. Examples of files you should put in this directory include
(but are not limited to) database cache files and downloadable
content, such as that used by magazine, newspaper, and map apps. Your
app should be able to gracefully handle situations where cached data
is deleted by the system to free up disk space.
Most probably you are using caches/temp directory which the system can clear contents of in case of low space. To avoid deletion use Documents Directory.
If you are already storing in documents directory, then the file can appear missing if you are storing its hardcoded path , which can change during app update. Try storing relative path and log the contents of your documents directory to see what files exist.
save the files in your local sqlite db, data core or if you can serialize them with the standard user defaults

Resources