3

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?

maxisme
  • 3,974
  • 9
  • 47
  • 97
  • 1
    Changing `NSOpenPanel *openPanel = [[NSOpenPanel alloc] init]` to `NSOpenPanel *openPanel = [NSOpenPanel openPanel];` I think may have helped a little with the showing of the window but still hangs after chosen. – maxisme Feb 14 '18 at 13:01
  • 1
    Why do you do `[NSApp activateIgnoringOtherApps:YES]`, `[openPanel setLevel:NSFloatingWindowLevel]` and `[openPanel setCanCreateDirectories:dir];`? – Willeke Feb 14 '18 at 16:06
  • Comes from a menu bar application `(1,2)`. Because I want to be able to create a directory (path) `(3)`. – maxisme Feb 14 '18 at 16:08
  • Can you post a crash log or backtrace? What does you app do after choosing a file/directory, can you post the code where the app crashes? – Willeke Feb 15 '18 at 13:06
  • @Willeke I cannot get it to crash anymore. I can only reproduce it hanging. Will post the code now. – maxisme Feb 15 '18 at 17:15
  • Which version(s) of macOS did you try? I presume you have a sandboxes app, could you post your entitlements file? Also did you try running it under a guest account (to eliminate all stuff that's cluttering the sandbox)? – mahal tertin Feb 20 '18 at 21:21

2 Answers2

3

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 .

mahal tertin
  • 3,239
  • 24
  • 41
1

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];
        }
    }];
}
theCoderGuy
  • 394
  • 2
  • 12
ingconti
  • 10,876
  • 3
  • 61
  • 48