NSURL appends '..' path component on returned url from URLByDeletingLastPathComponent which seems to contradict the documentation

The documentation for URLByDeletingLastPathComponent states the following:

If the receiver’s URL represents the root path, this property contains a copy of the original URL. Otherwise, if the original URL has only one path component, this property contains the empty string.

So maybe this is new in Foundation with the Golden Gate or maybe I just noticed this but the documentation above doesn't seem to be true. This will create an infinite loop:

NSURL *fileURL = [NSURL fileURLWithPath:@"/Users/MyUsername/Desktop/AFolder" isDirectory:YES];
		NSLog(@"%@",fileURL);
		
		NSURL *ancestorURL = fileURL.URLByDeletingLastPathComponent;
		while (ancestorURL != nil) 
		{
			NSURL *nextAncestor = ancestorURL.URLByDeletingLastPathComponent;
			NSLog(@"Next: %@",nextAncestor);
			
			if ([nextAncestor isEqual:ancestorURL]) 
			{
				NSLog(@"Hit the root - got a copy of the same url");
				break;
			}
			else if ([nextAncestor.absoluteString isEqualToString:@""] 
				    || [nextAncestor.path isEqualToString:@""])
			{
				NSLog(@"Empty string means we had only 1 path component.");
				break;
			}
			else if (nextAncestor == nil)
			{
				NSLog(@"Got nil");
				break;
			}
			ancestorURL = nextAncestor;
		}

The infinite loop can be avoided by adding the following condition:

else if (nextAncestor.pathComponents.count == 1)
{
// One path component.
	NSURL *sneakPeak = nextAncestor.URLByDeletingLastPathComponent;
				NSLog(@"%lu",sneakPeak.pathComponents.count); // Logs 2.
	 break;
}

When you get to one path component URLByDeletingLastPathComponent appends a .. path component rather than deleting a path component or returning a copy of the receiver or a url with an empty string..

If this sounds like a bug let me know. When I call URLByDeletingLastPathComponent on a url with only one path component I'd like to get nil. I think that would be a cleaner design.

Answered by DTS Engineer in 906788022

URL has been through a lot of changes recently, for a couple of reasons — relayering the Objective-C version on top of the Swift version and standards compliance — so…

This looks like a bug to me but at the very least the documentation should be updated to document IMO.

I agree that one or the other needs to change, and I encourage you to file a bug against the docs along those lines.

Please post your bug number, just for the record.

ps Once this lands, the canonical documentation for Foundation Essentials, which includes URL, will live in the Swift open source and you’ll be able to make changes like via that process.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

The documentation says it returns an empty string, not nil.

Just so you know, manually traversing URLs is always tricky. Sometimes you'll get a reference URL, which can't be traversed. And sometimes you'll get a ".nofollow" URL, which is undocumented.

Indeed. I checked for a url with an empty string but when I call URLByDeletingLastPathComponent on a file path url with only 1 component it does not return a url like that - it appends a path component with **.. **

And if you keep calling URLByDeletingLastPathComponent on the resulting URL (like I did in the dumb little sample above) it will continue to do so so you'll get file:///../../../../../ to infinity which is...weird.

This looks like a bug to me but at the very least the documentation should be updated to document IMO.

at the very least the documentation should be updated to document

Good luck with that.

It's kinda funny how much they've standardized on using URLs instead of file paths. But URLs are incredibly complicated and very poorly documented. They seem simple, but they aren't at all.

URL has been through a lot of changes recently, for a couple of reasons — relayering the Objective-C version on top of the Swift version and standards compliance — so…

This looks like a bug to me but at the very least the documentation should be updated to document IMO.

I agree that one or the other needs to change, and I encourage you to file a bug against the docs along those lines.

Please post your bug number, just for the record.

ps Once this lands, the canonical documentation for Foundation Essentials, which includes URL, will live in the Swift open source and you’ll be able to make changes like via that process.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I filed FB24921668

NSURL appends '..' path component on returned url from URLByDeletingLastPathComponent which seems to contradict the documentation
 
 
Q