spamguy spamguy - 6 months ago 27
Objective-C Question

Converting File Path From NSString To NSURL

I'm working through Cocoa smoothly, but this problem seems so basic it cancels out all the cool stuff I learned. :/

I have a generated file path, and it needs to be in NSURL format. From research, this is the code I wrote:

NSLog(@"Old path = %@", pathToFile);
NSURL *xmlURL = [[[NSURL alloc] init] fileURLWithPath:pathToFile];
NSLog(@"New path = %@", [xmlURL absoluteString]);


And the output:

2010-01-27 15:39:22.105 MusicLibraryStats[28574:a0f] Old path = file://localhost/Users/[username]/Music/iTunes/iTunes%20Music%20Library.xml
2010-01-27 15:39:22.105 MusicLibraryStats[28574:a0f] New path = (null)


First off, the alloc-init shouldn't even be necessary; other people seem to get away with it. In this case, if I don't alloc-init, I get an 'unrecognized selector' error on that line. Of course, now I'm just getting plain old (null).

Where did I goof?

Thanks!

Answer

The [[NSURL alloc] init] is not just unnecessary, it's invalid. fileURLWithPath: is a class method, which means you can only call it on the class object (that is, NSURL itself). It does not produce a compile error because -(NSURL *)init returns an object of type id, and does not result in a runtime error because -(NSURL *)init actually returns nil, and messages sent to nil will just cascade another nil as their return value.

This code should work:

NSString* pathToFile = @"/this/is/a/path";
NSURL* url = [NSURL fileURLWithPath:pathToFile];

I found your problem. -[NSOpenPanel URLs] returns an array of NSURL objects, which you treat as NSString objects. That's not right. You should use the following:

NSURL* url = [[oPanel URLs] objectAtIndex:0];

The debugger could've show you that if you looked at the pathToFile variable. Make sure to check it next time. :) Hovering a variable with your mouse should get you its type.

However, remember that there are situations where you will legitimately encounter another type than the one you expected. For instance, the private NSPathStore2 class is part of the NSString cluster, and you can do everything NSString supports on NSPathStore2 objects. (If this happens and you're not too sure, check the documentation to see if the type you expect is a cluster type. That's how they're called in the documentation.)