I've been trying to get a window to show up asking the person to choose a file, and I eventually did. The problem is, Xcode complains that the method I'm using is deprecated. I looked in the class reference, but everything under the "running panels" section has been deprecated as of Mac OS 10.6. Is there a different class I'm supposed to be using now?
Asked
Active
Viewed 1.1k times
3 Answers
30
In 10.6, there was a few changes to this classes. One of the benefits is that there is now a block-based API.
Here is a code snippet on how to use that:
NSOpenPanel *panel = [[NSOpenPanel openPanel] retain];
// Configure your panel the way you want it
[panel setCanChooseFiles:YES];
[panel setCanChooseDirectories:NO];
[panel setAllowsMultipleSelection:YES];
[panel setAllowedFileTypes:[NSArray arrayWithObject:@"txt"]];
[panel beginWithCompletionHandler:^(NSInteger result){
if (result == NSFileHandlingPanelOKButton) {
for (NSURL *fileURL in [panel URLs]) {
// Do what you want with fileURL
// ...
}
}
[panel release];
}];

Guillaume
- 21,685
- 6
- 63
- 95
-
2This looks like it's the correct code to use under 10.10, but get rid of the retain and release bits if you're using ARC. – Stewart Macdonald May 11 '15 at 09:30
-
Alternatively you can use [- beginSheetModalForWindow:completionHandler:](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSSavePanel_Class/#//apple_ref/occ/instm/NSSavePanel/beginSheetModalForWindow:completionHandler:) if you don't want a separate open dialog. – pi3 Dec 05 '15 at 16:35
27
As far as I know, you can use the runModal
method like shown below:
NSOpenPanel *openPanel = [[NSOpenPanel alloc] init];
if ([openPanel runModal] == NSOKButton)
{
NSString *selectedFileName = [openPanel filename];
}

Jesse Dunlap
- 1,280
- 1
- 16
- 22
-
4@Cole The reason you couldn't find this method is because it is implemented by `NSSavePanel`, which is `NSOpenPanel`'s superclass. +1 – ughoavgfhw Oct 08 '11 at 00:08
-
1The same is true of the other, better ways of running a save or open panel, including the method for running one as a sheet. – Peter Hosey Oct 08 '11 at 05:42
-
1In Xcode, alt-clicking `filename` in this code tells me that `[openPanel filename]` is deprecated as of 10.6. The replacement is `[openPanel URLs]` (as used in Guillaume's answer). – Ashley Jun 25 '14 at 11:19
-
5
Seeing how I found this question useful six years later, and since there are no swift answers, here's a swift solution.
You'll find two samples, one as a stand alone window and the other as a sheet.
Swift 3.0
func selectIcon() {
// create panel
let panel = NSOpenPanel()
// configure as desired
panel.canChooseFiles = true
panel.canChooseDirectories = false
panel.allowsMultipleSelection = false
panel.allowedFileTypes = ["png"]
// *** ONLY USE ONE OF THE FOLLOWING OPTIONS, NOT BOTH ***
// ********************** OPTION 1 ***********************
// use this if you want a selection window to display that is
// displayed as a separate stand alone window
panel.begin { [weak self] (result) in
guard result == NSFileHandlingPanelOKButton, panel.urls.isEmpty == false, let url = panel.urls.first else {
return
}
let image = NSImage.init(contentsOf: url)
DispatchQueue.main.async {
self?.iconImageView.image = image
}
}
// ********************** OPTION 2 ***********************
// use this if you want a sheet style view that displays sliding
// down from your apps window
panel.beginSheetModal(for: self.view.window!) { [weak self] (result) in
guard result == NSFileHandlingPanelOKButton, panel.urls.isEmpty == false, let url = panel.urls.first else {
return
}
let image = NSImage.init(contentsOf: url)
DispatchQueue.main.async {
self?.iconImageView.image = image
}
}
}

digitalHound
- 4,384
- 27
- 27
-
2So the `.begin` is a completion handler. For future on-lookers: You can also do: `let response = panel.runModal();if response == NSApplication.ModalResponse.OK {/*do things with panel.url*/}` Also works for `.CANCEL` – Sentry.co Aug 16 '17 at 11:40