iOS Temporary Folder Location

iOS temporary folder location

UPDATED 2016 ANSWER :

  • Data which is explicitly accepted by the user as personal, and potentially backuped in his/her iCloud space, should be written in user's "Documents" directory

  • Data that belongs and extends your application (an extension user can download for instance,...), but which is NOT in the bundle, should be written in a subfolder of "Application Support/" directory, having the title of your appID. It can also be the "Cache" directory.

  • Data with short-life time can be stored in the tmp directory of your application. In this case, use of NSTemporaryDirectory() is possible to get the "tmp" directory. Check this link for additional help.

Check this official iOS developement Apple page in section "Determining Where to Store Your App-Specific Files" for explanations.

Below are 3 functions in Swift designed to return NSURLs to these directories and make your like simpler.

Swift:

func GetDocumentsDirectory()->NSURL{
//returns User's "Documents" directory
//something like this on a real device : file:///private/var/mobile/Containers/Data/Application/APPID/Documents/
//something like this on the simulator : file:///Users/MACUSERID/Library/Developer/CoreSimulator/Devices/SIMDEVICEID/data/Containers/Data/Application/APPUUID/Documents/
let filemgr = NSFileManager.defaultManager()
let docsDirURL = try! filemgr.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)
return docsDirURL
}

func GetApplicationSupportDirectory()->NSURL{
//returns Application's support directory
//something like this on a real device : file:///private/var/mobile/Containers/Data/Application/APPID/Library/Application%20Support/YOURAPPBUNDLEID/
//something like this on the simulator : file:///Users/MACUSERID/Library/Developer/CoreSimulator/Devices/SIMDEVICEID/data/Containers/Data/Application/APPUUID/Library/Application%20Support/YOURAPPBUNDLEID/
let AllDirectories : [NSURL]
var ApplicationSupportDirectory : NSURL=NSURL.init()
var ApplicationDirectory : NSURL=NSURL.init()
AllDirectories=NSFileManager.defaultManager().URLsForDirectory(.ApplicationSupportDirectory, inDomains: .UserDomainMask)
if AllDirectories.count>=1{
ApplicationSupportDirectory=AllDirectories[0]
}
if !ApplicationSupportDirectory.isEqual(nil) {
ApplicationDirectory=ApplicationSupportDirectory.URLByAppendingPathComponent(NSBundle.mainBundle().bundleIdentifier!)
}
return ApplicationDirectory
}

func GetTemporaryDirectory()->NSURL{
//returns Application's temporary directory
//something like this on a real device : file:///private/var/mobile/Containers/Data/Application/APPID/tmp/
//something like this on the simulator : file:///Users/MACUSERID/Library/Developer/CoreSimulator/Devices/SIMDEVICEID/data/Containers/Data/Application/APPUUID/tmp/
return NSURL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
}

When does iOS clean the local app ./tmp directories?

According to the documentation, it could be any time, if the app is not executing:

The system may also purge lingering files from this directory when your app is not running.

It's logical to assume if a) your app is not running; and b) your device is running low on storage, then it's highly likely the system will, at some point, purge the contents of /tmp/.

It's also worth noting that the documentation states:

Your app should remove files from this directory when it determines they are no longer needed.

The emphasis here being on the app developer to do their own housekeeping and not leave it for the OS to tidy up after them.

How to get the url for a video saved in temporary directory

Since you don't seem to want your file to be visible to users or persisted between app launches, the Temporary directory sounds perfectly fine for your use case:

var tempVideoFileUrl: URL {
return FileManager.default.temporaryDirectory.appendingPathComponent("my_video_name")
}

func storeVideoToTemporaryFolder(videoData: Data) {
guard !FileManager.default.fileExists(atPath: tempVideoFileUrl.path) else {
return
}
do {
try videoData.write(to: tempVideoFileUrl)
}
catch {
fatalError()
}
}

func loadVideoFromTemporaryFolder() -> Data? {
if let data = try? Data(contentsOf: tempVideoFileUrl) {
return data
}
return nil
}

Worth mentioning though, the system may (and most likely will) purge this directory after the app is exited. It's recommended that you remove any temporary directories/files after they're no longer needed.

So in your case, you can simply remove it once you finished uploading to Firebase Storage:

func deleteVideoFromTemporaryFolder() {
do {
try FileManager.default.removeItem(at: videoFileUrl)
}
catch {
fatalError()
}
}

If you prefer to keep your file around between app launches though, you could use Application Support directory. But since Application Support and Documents directories gets automatically backed up, you may want to exclude your file from iCloud backup by setting its URL's isExcludedFromBackupKey key:

var applicationSupportVideoFileUrl: URL {
let applicationSupportFolderUrl = try! FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
return applicationSupportFolderUrl.appendingPathComponent("my_video_name")
}

func excludeFromCloudBackup(url: URL) {
var targetUrl = url
var isAlreadyExcludedFromBackup: Bool
do {
let storedRessourceValues = try targetUrl.resourceValues(forKeys: [URLResourceKey.isExcludedFromBackupKey])
isAlreadyExcludedFromBackup = storedRessourceValues.isExcludedFromBackup ?? false
}
catch {
fatalError()
}
guard !isAlreadyExcludedFromBackup else {
return
}
var ressourceValues = URLResourceValues()
ressourceValues.isExcludedFromBackup = true
do {
try targetUrl.setResourceValues(ressourceValues)
}
catch {
fatalError()
}
}

Edit: To get the data from your PHAsset, this should work:

import Photos

func loadVideoData(phAsset: PHAsset, completion: @escaping (Data?)->()) {
guard phAsset.mediaType == .video else {
return completion(nil)
}
let options = PHVideoRequestOptions()
options.isNetworkAccessAllowed = true
options.deliveryMode = .highQualityFormat
PHCachingImageManager().requestAVAsset(forVideo: phAsset, options: options) { (avAsset, _, _) in
guard let avUrlAsset = avAsset as? AVURLAsset else {
return
}
var videoData: Data?
do {
videoData = try Data(contentsOf: avUrlAsset.url)
} catch {
fatalError()
}
DispatchQueue.main.async {
completion(videoData)
}
}
}

Then simply call this method and store your video in the Temporary folder:

loadVideoData(phAsset: yourPhAsset) { [weak self] videoData in
guard let strongSelf = self else { return }
guard let videoData = videoData else {
return
}
strongSelf.storeVideoToTemporaryFolder(videoData: videoData)
}

iPhone storage in tmp directory

The OS will delete the temp directory on restart and at other indeterminate points. If you need to store something somewhere that you don't want backed up then use the cache directory. That will not be deleted and will not be backed up.

Your application will not be running when the temp is deleted nor will you have an opportunity to react to that deletion. This is fairly common behavior on all unix based platforms (OS X does this as well).

When do photos expire on iOS in /tmp/ folder

You have no control over the lifetime of files in the tmp/ folder. All you know is that the OS may purge such files any time your app is not running.

From the documentation:

Put temporary data in the tmp/ directory. Temporary data comprises any data that you do not need to persist for an extended period of time. Remember to delete those files when you are done with them so that they do not continue to consume space on the user’s device. The system will periodically purge these files when your app is not running; therefore, you cannot rely on these files persisting after your app terminates.

Open file using temporary storage

There is a temp directory for your app, you can review File System Basics to find more detail on the directories available to your app. You are expected to manage the life cycle of the files in question.

See this question for deleting a file from this directory.

The directory your interested in is tmp/

Form the documentation:

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.

Can't create temporary directory

The tempDirString string you are passing to fileManager.fileExists(atPath: tempDirString ) contains a string, but the string is NOT a file path. It is a description for human readable purposes, not for machine-readable purposes. In fact, it is not even a valid URL string (notice the space in it!).

If you want the path, replace this line:

let tempDirString = String( describing: tempDir )

and instead assign to tempDirString the results of the NSURL's path function to get the path as a string:

let tempDirString = tempDir.path

See: https://developer.apple.com/reference/foundation/nsurl/1408809-path



Related Topics



Leave a reply



Submit