My app is taking phantom space on my iPad's storage - ios

So, I'm working on an app for iPad that involves drawing.
It stores files in two places: the userDocument :
FileManager.default.url( for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true )
and the appSupportFolder:
FileManager.default.url( for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true )
What happens now is, iOS tells me my app is taking up 18GB of space on disk, even though i cleared all the document directory (using the finder, as this one is visible) and the support folder :
if let suppPath = try? FileManager.default.url( for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true ),
let URLs = try? FileManager.default.contentsOfDirectory( atPath: suppPath.path )
{
for url in URLs
{
let completePath = suppPath.appendingPathComponent( url )
try? FileManager.default.removeItem( at: completePath )
}
}
After this, i don't even know how to check the content of this folder, but i ran this :
func ScanDir( url: URL, depth: Int )
{
var string = ""
for _ in 0 ..< depth
{
string += "----"
}
string += "\(url.lastPathComponent)"
debugPrint( string )
if let URLs = try? FileManager.default.contentsOfDirectory( atPath: url.path )
{
for urlstring in URLs
{
ScanDir( url: url.appendingPathComponent( urlstring ), depth: depth+1 )
}
}
}
The result from the scan is then
"Application Support"
When before, i could see all my projects, exported files, brushes etc...
So it seemed to have worked.
But still, the app is up to 18GB.
Then i can uninstall it, but then as soon as I rebuild the app, it goes back.
I'm so confused right now ...

Alright, as it turns out, iOS automatically puts anything deleted from .documentDirectory in a hidden trash within that same folder.
So all images that i stored on .documentDirectory and then deleted, went in a .trash folder, that i have no idea how to see on the iPad, it just wouldn't let me know that there was this going on. I guess i'm not very familiar with iStuff yet.
So i had to run my cleaning sequence over this folder to get rid of it ..

Related

URLResourceValues not working for renaming a file

I have to rename some files in a directory in the Documents directory. I'm trying with URLResourceValues:
let fileURLs = try! FileManager.default.contentsOfDirectory(at: directory, includingPropertiesForKeys: nil)
fileURLS.forEach { fileURL in
// calculate newFileName
var resourceValues = URLResourceValues()
resourceValues.name = newFilename
var mutableFileURL = fileURL
try! mutableFileURL.setResourceValues(resourceValues)
}
After setting resourceValues.name I see this in the console...
key NSMutableString "NSURLNameKey" 0x00000001e7a8a368
value NSString "newName.jpg" 0x0000000283f61fe0
So that part is working. The try! completes without crashing so there were no errors thrown. But mutableFileURL is unchanged. It's got the old name, not the new name.
I see in the docs that setting read-only properties or setting properties not supported will be ignored and will not throw an error. But in my research I see this approach used commonly for renaming files. And I don't think it's a write access thing because if I use the old way it works fine:
try! FileManager.default.moveItem(at: fileURL, to: newFileURL)
What could I be missing here?
P.S. app targets iOS 14, running on a real device running iOS 16.1
You have not shown how you know things didn't work. But you say:
But mutableFileURL is unchanged
Your code isn't supposed to change mutableFileURL. If you're looking at mutableFileURL to see what happened, that's the problem.
The URL here is just a pointer to the file on disk. That's the whole point of the setResourceValues approach. Your code changes the name of the file on disk (and mutableFileURL, the pointer, is now invalid and should just be thrown away).
If you re-fetch the contents of the documents directory, you'll see that your code worked just fine.
Complete example, showing both what I think you are doing and how to do this correctly:
// --- create the file ---
let fm = FileManager.default
let docsurl = try fm.url(
for: .documentDirectory, in: .userDomainMask,
appropriateFor: nil, create: false
)
let newurl = docsurl.appending(path: "howdy.txt")
try "howdy".write(to: newurl, atomically: true, encoding: .utf8)
let arr = try fm.contentsOfDirectory(
at: docsurl, includingPropertiesForKeys: nil
)
arr.forEach { print($0.lastPathComponent) }
// howdy.txt
// --- rename the file ---
var values = URLResourceValues()
values.name = "hello.txt"
var mutableurl = newurl
try mutableurl.setResourceValues(values)
// --- how did we do? this is _not_ the way:
print(mutableurl)
// file:///.../Documents/howdy.txt
// --- how did we do? this _is_ the way
let arr2 = try fm.contentsOfDirectory(
at: docsurl, includingPropertiesForKeys: nil
)
arr2.forEach { print($0.lastPathComponent) }
// hello.txt

Swift list / delete all files in documents directory with progress

I would like to list (and later delete) all the files in the documents directory of my iOS app. Also I would like to use a Progress var to show progress (may be >1000 files). and Log "now deleteing file (fileName)"
extension FileManager {
func urls(for directory: FileManager.SearchPathDirectory, skipsHiddenFiles: Bool = true ) -> [URL]? {
let documentsURL = urls(for: directory, in: .userDomainMask)[0]
let fileURLs = try? contentsOfDirectory(at: documentsURL, includingPropertiesForKeys: nil, options: skipsHiddenFiles ? .skipsHiddenFiles : [] )
return fileURLs
}
}
The previous code list 3 folders in the documents directory (correct) but how do I get the list of all files in those folders and subfolders. I think I would need the total number of files for the totalUnitCount of the Progress object that will be used, right?

File name that saved in document directory have space character

I want to download video file and save it in the document directory but when i try show that downloaded video, i can't create URL of that file.
i'm using this code for create path for save file. my file name have spacing : (mobileslider video.mp4), and i want to save this video with own name but i can't create url path that contain space. how can solve this problem?
if let url = URL(string:videoURL){
showVideoFromNib(nibURL:url)
}
when i try to remove space from videoURL, showVideoFromNib method called but don't show the video. and when use orginal url, showVideoFromNib method didn't call.
Edit 1:
i change destination path from :
let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)
to :
let destination: DownloadRequest.DownloadFileDestination = { _, _ in
let pathComponent = "pack\(self.packID)-\(selectRow + 1).mp4"
let directoryURL: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let folderPath: URL = directoryURL.appendingPathComponent("Downloads", isDirectory: true)
let fileURL: URL = folderPath.appendingPathComponent(pathComponent)
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
now i can create URL and my show video method call but video don't show.
this is my new sample path:
/Users/MyUser/Library/Developer/CoreSimulator/Devices/2C2B6A39-5426-4E2C-B25A-CF64817AF26F/data/Containers/Data/Application/5A1BB109-D452-4F03-8820-EE1120E07C3D/Documents/Downloads/pack7-2.mp4
this file exist in this path but video player don't show this.
I solve problem. i'm using
let path = destinationUrl.absoluteString
instead of
let path = destinationUrl.path

Writing: Operation not permitted issue while working pdf

i am working on PDF File to read and write using Core Text .
Below code is to draw content on the PDF file .
let fileName = "pdffilename.pdf"
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDirectory = paths[0] as NSString
let pathForPDF = documentsDirectory.stringByAppendingString(fileName)
UIGraphicsBeginPDFContextToFile(pathForPDF, CGRectZero, nil)
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0,612,792), nil)
pagedataforPortaits()
UIGraphicsEndPDFContext()
This Code is working absolutely fine of simulator but when i am using a real device i am getting an Error
<Error>: CGDataConsumerCreateWithFilename: failed to open `/var/mobile/Containers/Data/Application/CADA69EB-8879-45EE-BBE0-477AC810BB86/Documentspdffilename.pdf' for writing: Operation not permitted.
deflateEnd: error -3: (null).
deflateEnd: error -3: (null).
<Error>: CGPDFContextCreate: failed to create PDF context delegate.
Any Suggestions ??
The path string needs a "/" separator between the documents directory and file name.
Swift 5.1:
let fileName = "pdffilename.pdf"
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = paths[0]
let pathForPDF = documentsDirectory + "/" + fileName

Print all filenames in a folder in iOS application

I have a folder with 4 subfolders in my iOS application with each of these containing about 20 files each. I would like to be able to iterate through each folder and print out the filenames. I am not sure how to go about doing this.
Here is what I have tried:
let docsPath = NSBundle.mainBundle().resourcePath! + "/Samples";
let fileManager = NSFileManager.defaultManager()
var error: NSError?
let docsArray = fileManager.contentsOfDirectoryAtPath(docsPath, error:&error)
println(docsArray)
This prints out nil. I expect it to print out each of the filenames. How do I make this happen?
You have two problems here:
1)
Check your built app to see if "Samples" is really ending up in the built binary. From the error of "The operation couldn’t be completed", I'm thinking you aren't copying "Samples" into the compiled app bundle or at least into the place you're expecting it to be.
2)
The call you're doing will give you the contents of the folder, but not the contents of the subfolders which is what you really want to list.
Use NSDirectoryEnumerator instead to get the contents of that folder and subfolders. Here is a related question that might give you one direction to go.
You can use the NSFileManager's enumerator if you want to get all the files including inside subdirectories.
Simple example:
if let enumerator = fileManager.enumeratorAtURL(docsPath, includingPropertiesForKeys: nil, options: nil, errorHandler: nil) {
while let url = enumerator.nextObject() as? NSURL {
println(url)
}
}
Nevermind, I figured it out:
var docsPath = NSBundle.mainBundle().resourcePath! + "/Snare";
let fileManager = NSFileManager.defaultManager()
var error: NSError?
let docsArray = fileManager.contentsOfDirectoryAtPath(docsPath, error:&error)
//println(error!.localizedDescription)
println(docsArray)
for filename in docsArray!
{
let subfolderPath = docsPath + "/"+(filename as! String)
println(docsPath)
let subarray = fileManager.contentsOfDirectoryAtPath(subfolderPath, error: &error)
println(subarray)
}

Resources