Question

I'm trying to make a Mac OS X application that asks the user for a directory. I'm using an NSOpenPanel that gets triggered when the user presses a "Browse" button.

The problem is, [NSOpenPanel filenames] was deprecated, so now I'm using the URLs function. I want to parse out the stuff that's url related to just get a normal file path. So I tried fileName = [fileName stringByReplacingOccurrencesOfString:@"%%20" withString:@" "];, but that gave me an error:

-[NSURL stringByReplacingOccurrencesOfString:withString:]: unrecognized selector sent to instance 0x100521fa0

Here's the entire method:

- (void) browse:(id)sender
{
    int i; // Loop counter.

    // Create the File Open Dialog class.
    NSOpenPanel* openDlg = [NSOpenPanel openPanel];

    // Enable the selection of files in the dialog.
    [openDlg setCanChooseFiles:NO];

    // Enable the selection of directories in the dialog.
    [openDlg setCanChooseDirectories:YES];

    // Display the dialog.  If the OK button was pressed,
    // process the files.
    if ( [openDlg runModal] == NSOKButton )
    {
        // Get an array containing the full filenames of all
        // files and directories selected.
        NSArray* files = [openDlg URLs];

        // Loop through all the files and process them.
        for( i = 0; i < [files count]; i++ )
        {
            NSString* fileName = (NSString*)[files objectAtIndex:i];
            NSLog(@"%@", fileName);

            // Do something with the filename.
            fileName = [fileName stringByReplacingOccurrencesOfString:@"%%20" withString:@" "];

            NSLog(@"%@", fileName);
            NSLog(@"Foo");
            [oldJarLocation setStringValue:fileName];
            [self preparePopUpButton];
        }
    }
}

Interestingly enough, "Foo" never gets outputted to that console. It's like the method aborts at the stringByReplacigOccurencesOfString line.

If I remove that one line, the app will run and fill my text box with the string, just in URL form, which I don't want.

Was it helpful?

Solution

Your problem is that the NSArray returned by [NSOpenPanel URLs] contains NSURL objects, not NSString objects. You're doing the following cast:

 NSString* fileName = (NSString*)[files objectAtIndex:i];

Since NSArray returns an id, there isn't any compile-time checking to make sure your cast makes sense, but you do get a runtime error when you try to send an NSString selector to what is actually an NSURL.

You could convert the NSURL objects to NSString and use your code mostly as-is, but there's no need for you to handle the URL decoding yourself. NSURL already has a method for retrieving the path portion which also undoes percent-encoding: path.

NSString *filePath = [yourUrl path];

Even if your code was dealing with just a percent-encoded NSString, theres stringByReplacingPercentEscapesUsingEncoding:.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top