I'm trying to understand the sample from Apple "ComplexBrowser", but it's really hard to find any material/tutorial to "CFURLEnumeratorCreateDirectoryURL".
ComplexBrowser Sample from Apple
What exactly is going on in this piece of code?
I didn't understand this way of looping with CFURLEnumeratorGetNextURL and stuff.
For me, the approach with NSFileManager seems simpler, but more limited?
NSArray *contentsAtPath = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:parentPath error:NULL];
- (NSArray *)children {
if (_children == nil || _childrenDirty) {
// This logic keeps the same pointers around, if possible.
NSMutableArray *newChildren = [NSMutableArray array];
CFURLEnumeratorRef enumerator = CFURLEnumeratorCreateForDirectoryURL(NULL, (CFURLRef) _url, kCFURLEnumeratorSkipInvisibles, (CFArrayRef) [NSArray array]);
NSURL *childURL = nil;
CFURLEnumeratorResult enumeratorResult;
do {
enumeratorResult = CFURLEnumeratorGetNextURL(enumerator, (CFURLRef *) &childURL, NULL);
if (enumeratorResult == kCFURLEnumeratorSuccess) {
FileSystemNode *node = [[[FileSystemNode alloc] initWithURL:childURL] autorelease];
if (_children != nil) {
NSInteger oldIndex = [_children indexOfObject:childURL];
if (oldIndex != NSNotFound) {
// Use the same pointer value, if possible
node = [_children objectAtIndex:oldIndex];
}
}
[newChildren addObject:node];
} else if (enumeratorResult == kCFURLEnumeratorError) {
// A possible enhancement would be to present error-based items to the user.
}
} while (enumeratorResult != kCFURLEnumeratorEnd);
[_children release];
_childrenDirty = NO;
// Now sort them
_children = [[newChildren sortedArrayUsingComparator:^(id obj1, id obj2) {
NSString *objName = [obj1 displayName];
NSString *obj2Name = [obj2 displayName];
NSComparisonResult result = [objName compare:obj2Name options:NSNumericSearch | NSCaseInsensitiveSearch | NSWidthInsensitiveSearch | NSForcedOrderingSearch range:NSMakeRange(0, [objName length]) locale:[NSLocale currentLocale]];
return result;
}] retain];
}
return _children;
}
Since this information is stored in an opaque C data type, in core foundation they provide C routines which give you information about the data. This is a form of encapsulation so that they can change things behind the scenes and not effect the public interface for the library.
Basically, they create a loop and keep asking for the next URL from the directory until they find the end of the directory.
enumerator
is kind of an index that keeps track of where they are in the list of URL's.enumeratorResult
tells us whether or not we got a new URL (or there
is an error, or we are at the last record).As it goes through each URL, it creates FileSystemNode
's and adds them to an array, and then returns the array when it is done looping through all of the URL's in the directory.