Filemanager won't remove file

I'm trying to remove a file in the Documents directory, but it says that the file doesn't exist! Here's my coding:


let zipFiles = documentSTRINGS.filter{$0.hasSuffix("zip")}
....
....


do{
print (zipFiles)
try FileManager.default.removeItem(atPath: zipFiles.first!)
}
catch{
print (error)
}


zipFiles prints ["file:///private/var/mobile/Containers/Data/Application/XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX/Documents/Accoltus.zip"]. So I know the file exists, but it's printing the following error:

Error Domain=NSCocoaErrorDomain Code=4 "“Accoltus.zip” couldn’t be removed." UserInfo={NSFilePath=file:/

Remove

), NSUnderlyingError=0x1c445d730 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}


This isn't making any sense. Does anyone have any clue why this is happening?

Answered by QuinceyMorris in 291613022

No, your zipFiles array consists of a URL string (it has the "file:" scheme at the start of it), so it's not a file path.


Whatever is producing your documentSTRINGS array is putting the wrong thing in that array.


P.S. In general, do not use path-based APIs like "removeItem(atPath:)". Use URL-based APIs instead, such as "removeItem(at:)".

Accepted Answer

No, your zipFiles array consists of a URL string (it has the "file:" scheme at the start of it), so it's not a file path.


Whatever is producing your documentSTRINGS array is putting the wrong thing in that array.


P.S. In general, do not use path-based APIs like "removeItem(atPath:)". Use URL-based APIs instead, such as "removeItem(at:)".

OK, I'll switch to URL. Out of curiosity, why should I avoid Strings?


This is how I get my documentSTRINGS:


let docDir = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let docuURLS = try! FileManager.default.contentsOfDirectory(at: docDir, includingPropertiesForKeys: nil)

for urls in docuURLS{
     let string = urls.relativeString
     docuSTRINGS.append(string)
             
}


I have to use Strings in some areas in order to separate different file types.

Path strings are problematic for a couple of reasons. One is that the file system uses a fixed character encoding, which makes using Unicode string a bit treacherous, since you have to be certain whether you string is "fileSystemEncoding" or not, at any given time. Also, persistent sandbox security permissions are associated only with URLs, not paths, which may affect some apps. Also, URLs can in theory locate files in a wider selection of locations, including on the web, or using a wider selection of access schemes.


For such reasons, it's recommended these days to use URLs in preference to paths.

What QuinceyMorris said but also…

URLs can carry other information that can, in some circumstances, radically improve performance. For example, when you enumerate a directory using

contentsOfDirectory(at:includingPropertiesForKeys:options:)
, you can pass in a set of property keys that you’re interested in. The enumeration code will do the enumeration and cache the property values in each returned URL. Later on, when you fetch the property value using
resourceValues(forKeys:)
, it gets it from the cache rather than hitting the file system. This is important when dealing with volumes that have a long latency, most notably network volumes on macOS, because you can enumerate a directory and get all of the values of interest in one round trip. Even with local volumes, where the latency is much lower, it’s still performs significantly better.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Filemanager won't remove file
 
 
Q