I am saving media data to the iPhones tmp directory and after it is no longer needed I delete all the files. However I have noticed in my phones settings menu, under storage that my applications memory is increasing every time I save a new file and then later delete it. I am pretty sure the files are being removed because if I try to delete the same file again it throws an exception that it doesn't exist. Here is my code for deleting everything in tmp:
let content = try FileManager.default.contentsOfDirectory(atPath: NSTemporaryDirectory())
for path in content {
let fullPath = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(path)
try FileManager.default.removeItem(atPath: fullPath.absoluteString)
}
The weird thing is that sometimes after not using the application and coming back the memory goes down, keyword being sometimes. Am I doing something wrong and/or is there anything else I can do to minimize the memory footprint of my application in regards to the tmp folder?
It turns out passing it a NSURL vs string was the solution, now the files are definitely being deleted:
for path in content2 {
let filePath = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(path)
try FileManager.default.removeItem(at: filePath!)
}
Related
I am adding an option in my App to backup everything to a file.
For that, I am serializing all my objects to a dictionary that I save in a single file in the path provided by FileManager.default.temporaryDirectory. Then I ask the user for a path to save this file using a UIDocumentPickerViewController.
Everything works fine, but I wonder what happens with the temporal file that I created in the temporaryDirectory. Is this automatically removed by the operating system? should I take care of removing it by myself?
This is how I get the path of the temporary directory for my file:
private var exportURL: URL {
let documentURL = FileManager.default.temporaryDirectory
let fileName = "archive"
let filePath = "\(fileName).backup"
return documentURL.appendingPathComponent(filePath)
}
My app writes files to the users shared Documents directory. I save the files path but this breaks if the user changes the documents name, moves the document to a new location etc. Is there some kind of persistent file id i can use to keep track of these documents?
i've been poking around
FileManager.default.attributesOfItem(atPath: docUrl.path)
and i find attributes like FileAttributeKey.systemFileNumber but this number seems to change every time i run the app. There has to be some way to keep track of files other than their path
You need to use url bookmarks, like the following (sketch)
if let bookmark = try? URL(fileURLWithPath: docUrl.path)
.bookmarkData(includingResourceValuesForKeys: nil,
relativeTo:nil) {
// store somewhere persistent bookmark to your file
}
...
let bookmark = // read bookmark from persisten storage
var stale = false
if let url = try? URL(resolvingBookmarkData:bookmark, bookmarkDataIsStale: &stale) {
// work with resolved url
} else {
// file disappeared - handle the situation
}
I must be missing something simple - I'm trying to iterate through the
files in an .scnassets folder but can't seem to get a reference to the
folder/catalog.
Here's the organizer:
Models.scnassets contains one file. I tried this:
let fileManager = FileManager.default
let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
let docsURL = urls.first
let assetFolderPath = docsURL?.appendingPathComponent("Models.scnassets").path
And I tried this and several other variants:
let modelPathString = "ARAds/Models.scnassets"
Then I attempted to count the files with both of the above paths:
do {
let modelPathDirectoryFiles = try fileManager.contentsOfDirectory(atPath: assetFolderPath!)
//or modelPathString
print(modelPathDirectoryFiles.count)
} catch {
print("error getting list of files")
}
I get the error message in all cases.
I assume there must be some special way to get a reference to a SceneKit
Catalog but I have not been able to find that in the Apple docs nor SO.
Any guidance would be appreciated. iOS 11.4 Xcode 10.0
Looking at your code, the first thing I see, is that you are referencing the Documents Directory which isn't actually where your folder is.
The Documents Directory is a folder on your actual device where you might save user data or other files which can be accessed at a latter date (for example via iTunes Sharing).
If you move your Models.scnassets folder under the yellow ArAds folder you should be able to access your content like so:
let myModelToLocate = SCNScene(named: "Models.scnassets/Phone_01.scn")
Hope it helps...
You've pointed me in a better direction, but I can already get the scn and make a node if I know the name. What I really want to do is populate a tableview with the options that are available - so I need to find the current list of scene files.
I think this will work:
let subdir = Bundle.main.resourceURL!.appendingPathComponent("Models.scnassets").path
do {
let modelPathDirectoryFiles = try fileManager.contentsOfDirectory(atPath: subdir)
print(modelPathDirectoryFiles.count) //this works
//then do my thing with the array
} catch {
print("error getting list of files")
}
This seems to work, whether I move the folder or not.
I got little problem, I am downloading PDF and saving to location, I am using write method to save to location and everything seems to work on version iOS 10 and below, but I got problem with iOS11, I am getting false from method below, I checked path, and bytes and it is same on both devices.
(try? data.write(to: invoiceFileUrl, options: [.atomic])) != nil
try this
let data = NSData(contentsOf:url! as URL)
data?.write(to:invoiceFileUrl, atomically: true)
Have you tried simply moving the file around? I am guessing you are using URLSession to download said file ( or you should anyway ).
Then you can use FileManager to move the temporary file to your documents or whatever desired directory in your app's container.
FileManager.default.moveItem(at:temporaryURL, to: destinationURL)
In case you prefer using paths there is also:
FileManager.default.moveItem(atPath: temporaryPath, toPath: destinationPath)
Though I personally don't use paths often (anymore) because it can lead to a whole load of inconsistencies and other issues you just don't want to deal with. Whatever backend you have try to move to NSURL or URL as quickly as you can with any received data; it'll make your life easier and most importantly more consistent accross foundation API's.
moveItemAtURL - Foundation documentation
I'd like to persist images to user domain of iPhone so I write the following code.
let path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0]
print(path)
It shows like: /Users/xxx/Library/Developer/CoreSimulator/Devices/1312F880-6BDC-45D2-B3B3-4D2374313C67/data/Containers/Data/Application/A2850237-5E71-4373-81A6-B443032E1951/Documents/
In this case, Application ID is A2850237-5E71-4373-81A6-B443032E1951
And the problem is when I run on simulator again WITHOUT REMOVING THE APP, it shows like: /Users/xxx/Library/Developer/CoreSimulator/Devices/1312F880-6BDC-45D2-B3B3-4D2374313C67/data/Containers/Data/Application/1F9B5B0A-5A6C-4098-BF40-C978C60C93AF/Documents/
In this case, Application ID is 1F9B5B0A-5A6C-4098-BF40-C978C60C93AF
So there are Application ID difference between previous and current install although I just did update the app and didn't remove the app. Why it is caused and how to fix it?
It causes Xcode 7.2, 7.1, 7.0. And it causes with not only simulator install but also actual device install. So if iOS users update the app from app store, the Application ID will be changed and app sandbox will also be changed and finally users cannot refer their images.
Similar Situations:
Xcode 6.3 seems to change the path to the Documents directory per app run
xcode 6.2 create a new simulator path every time when run the app
Related Guidelines:
File System Basics
Thanks in advance.
EDIT
It seems I have to persist path as relative not absolute.
Application folder name changes every time i run in simulator [duplicate]
Xcode 6 keeps renaming my app's directory in iOS8 simulator after each run.
I'll try the approach and if I solved my problem, I'll update the question.
I have to persist path relative not absolute. And I also can salvage old run images by fetching with NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] + "persisted relative path".
A better solution is to save a bookmark data
https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/AccessingFilesandDirectories/AccessingFilesandDirectories.html
A bookmark is an opaque data structure, enclosed in an NSData object,
that describes the location of a file. Whereas path- and file
reference URLs are potentially fragile between launches of your app, a
bookmark can usually be used to re-create a URL to a file even in
cases where the file was moved or renamed
First you must use NSURL instead of String
Convert an NSURL to NSData
let data: NSData? = try? url.bookmarkDataWithOptions(.SuitableForBookmarkFile, includingResourceValuesForKeys: nil, relativeToURL: nil)
Read an NSURL from bookmark NSData
var isStale: ObjCBool = false
let url = try? NSURL(
byResolvingBookmarkData: bookData,
options: [],
relativeToURL: nil,
bookmarkDataIsStale: &isStale)
guard let fullURL = url else {
return nil
}
You can fill relativeToURL to your document directory url
Alternatively you can use FileKit : path.bookmarkData and Path(bookmarkData: ..)
try to persist your file just with the name.extension
to save document
let pathDocument = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0]
let fullPath = let fullPath = pathDocument+"/"+"fileName.ext"
//...add some code to save document at `fullPath`...
to get document
let pathDocument = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0]
let fullPath = let fullPath = pathDocument+"/"+"fileName.ext"
//... add code to get data at path : `fullPath`....