maxisme
maxisme

Reputation: 4265

How to acquire a file path using objective c

I want a function which just returns the full file path of a file selected in finder.

I am currently have this function:

+ (NSString*)choosePathWindow:(NSString*)title buttonTitle:(NSString*)buttonTitle allowDir:(BOOL)dir allowFile:(BOOL)file{
    [NSApp activateIgnoringOtherApps:YES];

    NSOpenPanel *openPanel = [NSOpenPanel openPanel];
    [openPanel setLevel:NSFloatingWindowLevel];
    [openPanel setAllowsMultipleSelection:NO];
    [openPanel setCanChooseDirectories:dir];
    [openPanel setCanCreateDirectories:dir];
    [openPanel setCanChooseFiles:file];
    [openPanel setMessage:title];
    [openPanel setPrompt:buttonTitle];

    NSString* fileName = nil;
    if ([openPanel runModal] == NSModalResponseOK)
    {
        for( NSURL* URL in [openPanel URLs])
        {
            fileName = [URL path];
        }
    }
    [openPanel close];
    return fileName;
}

But this usually behaves awfully and stutters into view and often hangs after choosing a file (I have an i7-7700k and 16GB ddr4) and always hangs when clicking cancel. I also believe that this may be to do with external network mounts I have. But any other software such as PHPStorm or Chrome work fine with the same window.

Is there a better way to do this?

Upvotes: 3

Views: 1015

Answers (2)

mahal tertin
mahal tertin

Reputation: 3414

The code looks fine. Try calling your function from main thread; modal dialogs need this and usually don't enforce it themselves. In any case the Powebox (the thing that runs NSOpenPanel in sandbox) is a bit of a beast. Also you might get different results with debug build launched directly from Xcode (not so good) and release build launched from Finder.

To test NSOpenPanel: Try running your App under a guest account to eliminate all stuff that's cluttering the sandbox .

Upvotes: 3

ingconti
ingconti

Reputation: 11666

My code: (actually in production:)

-(void)OpenIt {
    NSOpenPanel* panel = [NSOpenPanel openPanel];

    // This method displays the panel and returns immediately.
    // The completion handler is called when the user selects an
    // item or cancels the panel.

    [panel setTitle: "title...."];
    NSString *title = NSLocalizedString(@"CHOOSE_FILE", @"");
    [panel setMessage: title];

    [panel beginWithCompletionHandler:^(NSInteger result){
        if (result == NSFileHandlingPanelOKButton) {
            NSURL*  theDoc = [[panel URLs] objectAtIndex:0];
            NSLog(@"%@", theDoc);
            // Open  the document using url
            [self openUsingURL: theDoc];
        }
    }];
}

Upvotes: 1

Related Questions