Issue with returning a Directory Enumerator from NSFileManager using enumeratorAtUrl in Swift
Try this:
let enumerator:NSDirectoryEnumerator = manager.enumeratorAtURL(url, includingPropertiesForKeys: keys, options: NSDirectoryEnumerationOptions(), errorHandler: nil)
Or in short, pass in NSDirectoryEnumerationOptions()
instead of "0
".
"0" is not really a member of the enumeration it is looking for.
NSFileManager:enumeratorAtURL: returns a different form of URL to NSFileManager:URLForDirectory
I had to switch to doing this instead:
NSDirectoryEnumerator *dirEnum = [self.fileManager enumeratorAtPath: [NSHomeDirectory() stringByAppendingPathComponent:@"/Library/Application Support/"]];
FileManager.default.enumerator does not return any files
FileManager
has two methods to obtain a directory enumerator:
enumerator(atPath path: String)
enumerator(at url: URL, ...)
The first one returns an enumerator which enumerates strings
(the file paths), the second one returns an enumerator which
enumerates URLs.
Your code uses the URL-based enumerator, therefore the conditional
casts to as? String
fail and no output is produced.
You have to cast to URL
instead:
if let dirContents = FileManager.default.enumerator(at: documentsUrl.resolvingSymlinksInPath(), includingPropertiesForKeys: nil) {
while let url = dirContents.nextObject() as? URL {
print(url.path)
}
}
You can also iterate with a for-loop:
if let dirContents = FileManager.default.enumerator(at: documentsUrl.resolvingSymlinksInPath(), includingPropertiesForKeys: nil) {
for case let url as URL in dirContents {
print(url.path)
}
}
Enumerating over a directory gives me an error when I try to follow aliases
I‘m pretty damn sure the answer is right there in the error message:
The file “Musik” couldn’t be opened because you don’t have permission to view it.
Reveal the destination of the alias in the Finder application and check its permission via “Get Info” or ls -l@
in the Terminal — I’d bet that your user account david
is not being granted one of the following permissions:
read
execute
list
The last one will typically not be visible on the command line except in combination with an explicit deny
-access-control-entry.
How do I enumerate through a directory in Objective-C, and essentially clear out all the directories of non-directory files?
Something like this will work:
NSURL *rootURL = ... // File URL of the root directory you need
NSFileManager *fm = [NSFileManager defaultManager];
NSDirectoryEnumerator *dirEnumerator = [fm enumeratorAtURL:rootURL
includingPropertiesForKeys:@[NSURLNameKey, NSURLIsDirectoryKey]
options:NSDirectoryEnumerationSkipsHiddenFiles
errorHandler:nil];
for (NSURL *url in dirEnumerator) {
NSNumber *isDirectory;
[url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:NULL];
if (![isDirectory boolValue]) {
// This is a file - remove it
[fm removeItemAtURL:url error:NULL];
}
}
Why is NSDirectoryEnumerator picking up hidden files here?
Actually, the real problem is that you're using the wrong operator to specify the mask:
NSDirectoryEnumerationSkipsPackageDescendants || NSDirectoryEnumerationSkipsHiddenFiles
does Boolean OR
, giving you 1
, which isn't a useful options mask. You need to use the single pipe:
NSDirectoryEnumerationSkipsPackageDescendants | NSDirectoryEnumerationSkipsHiddenFiles
which is bitwise OR
.
OLD ANSWER:
You need to actually request the properties that you're going to look at:
dirEnumerator = [fileManager enumeratorAtURL:item
includingPropertiesForKeys:[NSArray arrayWithObject:NSURLIsHiddenKey]
options:NSDirectoryEnumerationSkipsPackageDescendants || NSDirectoryEnumerationSkipsHiddenFiles
errorHandler:nil];
from the -[NSURL getResourceValue:forKey:error:]
doc:
Discussion
value is set to nil if the requested resource value is not defined for the URL. In this case, the method still returns YES.
NSFileManager delete contents of directory
E.g. by using a directory enumerator:
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtPath:path];
NSString *file;
while (file = [enumerator nextObject]) {
NSError *error = nil;
BOOL result = [fileManager removeItemAtPath:[path stringByAppendingPathComponent:file] error:&error];
if (!result && error) {
NSLog(@"Error: %@", error);
}
}
Swift
let fileManager = NSFileManager.defaultManager()
let enumerator = fileManager.enumeratorAtURL(cacheURL, includingPropertiesForKeys: nil, options: nil, errorHandler: nil)
while let file = enumerator?.nextObject() as? String {
fileManager.removeItemAtURL(cacheURL.URLByAppendingPathComponent(file), error: nil)
}
File count of a directory in Objective-C
Straight from the docs:
If you need to recurse into subdirectories, use
enumeratorAtURL:includingPropertiesForKeys:options:errorHandler: as
shown in “Using a Directory Enumerator”).
Check also here:
Using a Directory Enumerator
Related Topics
Uimarkuptextprintformatter and MAC Catalyst
Sknode Subclass Generates Error: Cannot Invoke Initializer for Type "X" with No Arguments
Bad_Access During Recursive Calls in Swift
Ckasset in Server Record Contains No Fileurl, Cannot Even Check for Nil
Struct Memberwise Initialization - Omitting Values for Properties That Have Defaults
What's The Difference Between [String] VS. [(String)]
+' Is Deprecated: Mixed-Type Addition Is Deprecated in Swift 3.1
Filter on Calayer Except for a Shape Which Is an Union of (Non Necessarily Distinct) Rectangles
How to Decode a Utf16 String into a Unicode Character
Location Access Request in iOS 11
How to Create Generic Convenience Initializer in Swift
Scrolltoitem at Indexpath at .Top Hides Cell Under Header When Sectionheaderspintovisiblebounds
Produce Sounds of Different Frequencies in Swift
Convert/Wrap Swift Struct as Nsvalue for Caanimation Purposes
Type 'Int' Does Not Conform to Protocol 'Booleantype'