How to acquire a file path using objective c - 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?

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 .

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];
}
}];
}

Related

Get file path from dialog box and print to NSLog (Cocoa Objective-C)

I have a project that opens a file browser and when I select and open a file, I would like to print the file path for testing.
Here is my .main file:
#implementation SaveMenuCntroller
- (IBAction)askUserForImage:(id)sender {
NSOpenPanel* panel = [NSOpenPanel openPanel];
// Let the user select any images supported by
// the NSImage class.
NSArray* imageTypes = [NSImage imageTypes];
[panel setAllowedFileTypes:imageTypes];
[panel beginWithCompletionHandler:^(NSInteger result){
if (result == NSFileHandlingPanelOKButton) {
}
}];
}
#end
Anyone have experience with this that could help?
You can do this:
NSLog(#"selected file: %#", panel.URLs);
The URLs property is an array to support multiple selection. You could also do:
NSLog(#"selected file: %#", panel.URLs.firstObject);
And, finally, if you really want a path string instead of a URL, do:
NSLog(#"selected file: %#", [panel.URLs.firstObject path]);

NSOpenPanel reopening after selection

Some users are reporting that they cannot select files in my sandboxed app because when they select and item it reopens.
Nowhere in my code am I reopening the panel so I'm a bit confused as to why this would be happening.
One of my users said that the following message was logged in console a number of times:
"Keychain sandbox consume extension error: s=-1 p= cannot allocate memory"
I've asked them to run first aid on their keychain, and repair their disk permissions but that hasn't helped.
Does anyone have any ideas what could be causing this?
Thank you!
Here is the code that triggers the NSOpenPanel:
- (IBAction)selectHomeDirectory:(id)sender {
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
[openPanel setTitle:#"Select your home folder"];
[openPanel setMessage:#"Select your home folder..."];
[openPanel setPrompt:#"Choose"];
[openPanel setCanCreateDirectories:NO];
[openPanel setCanChooseFiles:NO];
[openPanel setCanChooseDirectories:YES];
[openPanel setExtensionHidden:YES];
[openPanel setAllowedFileTypes:nil];
[openPanel setAllowsMultipleSelection:NO];
[openPanel setDelegate:self];
[openPanel setDirectoryURL:[NSURL fileURLWithPath:#"/Users/"]];
[openPanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
if(result != NSOKButton || !openPanel.URL){
return;
}
/* Saves the scoped URL, and then triggers a view change */
}];
}
This turned out to be a Mavericks issue that was fixed in the later seeds.

NSOpenPanel not opening all the time?

OK, this is my issue :
I have an application with one window (an NSPanel actually)
I'm trying to open and NSOpenPanel and get some input
I may have to push the trigger button like 2-3 times, before it opens up...
This is my code :
- (IBAction)doExport:(id)sender
{
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
[openPanel setCanChooseFiles:NO];
[openPanel setCanChooseDirectories:YES];
NSInteger rezult = [openPanel runModal];
if (rezult == NSFileHandlingPanelOKButton)
{
NSString* dir = [[openPanel URL] path];
// do the processing here
}
}
What's going on???

Get filepath File Open Dialog box cocoa?

I have a File Open Dialog box in my application to select files from, but when the user clicks the 'Select' button in the box, it obviously won't do anything. How do I extract the filepath from the selected file? I need the filepath so I can get the contents of the file to encrypt. Initially, I hard coded the file I would use into my application, but that was only for testing purposes. Here is what I am using for the File Open Dialog Box:
int i;
NSOpenPanel* openDlg = [NSOpenPanel openPanel];
[openDlg setCanChooseFiles:YES];
[openDlg setCanChooseDirectories:YES];
[openDlg setPrompt:#"Select"];
NSString *fileName = [pathAsNSString lastPathComponent];
[fileName stringByDeletingPathExtension];
if ([openDlg runModalForDirectory:nil file:nil] == NSOKButton )
{
NSArray* files = [openDlg filenames];
for( i = 0; i < [files count]; i++ )
{
[files objectAtIndex:i];
}
}
Thanks so much for the help.
Use - (NSArray *)URLs method instead of filenames.
Your code is already handling the files that the user has selected, you're just not doing anything with them.
The array returned from the ‑filenames method contains the paths to the files that the user selected as NSString objects. If they have only selected one file, there will only be one object in the array. If they have selected no files, the array will be empty.
if ([openDlg runModalForDirectory:nil file:nil] == NSOKButton )
{
NSArray* files = [openDlg filenames];
for(NSString* filePath in [openDlg filenames])
{
NSLog(#"%#",filePath);
//do something with the file at filePath
}
}
If you only want the user to be able to select a single file, then call [openPanel setAllowsMultipleSelection:NO] when you're configuring the panel. That way, there will be a maximum of one entry in the filenames array.
As #VenoMKO points out, the ‑filenames method is now deprecated and you should use the ‑URLs method instead. This will return an array of file NSURL objects rather than an array of NSStrings. Since pretty much all the file handling APIs in Snow Leopard were revised to take URLs, this would be the preferred option.
You Want to Get File Path Using Following Code
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
[openPanel setCanChooseFiles:YES];
[openPanel setCanChooseDirectories:NO];
[openPanel setAllowsMultipleSelection: NO];
[openPanel setAllowedFileTypes:ArrExtension ];
if ([openPanel runModal] == NSOKButton ){
NSString *FilePath = [NSString stringWithFormat:#"%#",[openPanel URL]];
[openPanel canHide];
}

Using Cocoa to create an icon for a folder

In my Mac OS application, I'm prompting a user to create a new folder. I would like to apply an icon to this folder using Cocoa when it is created. Currently, to create the folder, I'm using the following code:
- (IBAction)browseFiles:(id)sender
{
NSOpenPanel *oPanel = [[NSOpenPanel openPanel] retain];
[oPanel setCanChooseDirectories:YES];
[oPanel setCanChooseFiles:NO];
[oPanel setDelegate:self];
[oPanel setCanCreateDirectories:YES];
[oPanel beginSheetForDirectory:NSHomeDirectory()
file:nil
types:nil
modalForWindow:nil
modalDelegate:self
didEndSelector:#selector(filePanelDidEnd:
returnCode:
contextInfo:)
contextInfo:nil];
}
After choosing a directory, the user clicks a confirm button that calls a function with the following method:
bool set = [[NSWorkspace sharedWorkspace] setIcon:[NSImage imageNamed:#"icon.icns"] forFile:path options:NSExcludeQuickDrawElementsIconCreationOption];
While the piece of code above does return "YES", the icon is not successfully applied to the folder. Am I doing something wrong in my code?
Thanks.
The NSWorkspace method works like a charm here. Maybe your icon is in an invalid format?
I tried setIcon: using the Finder icon:
- (IBAction)setFolderIcon:(id)sender
{
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
[openPanel setCanChooseFiles:NO];
[openPanel setCanChooseDirectories:YES];
switch([openPanel runModal])
{
case NSFileHandlingPanelOKButton:
{
NSURL* directoryURL = [openPanel directoryURL];
NSImage* iconImage = [[NSImage alloc] initWithContentsOfFile:#"/System/Library/CoreServices/Finder.app/Contents/Resources/Finder.icns"];
BOOL didSetIcon = [[NSWorkspace sharedWorkspace] setIcon:iconImage forFile:[directoryURL path] options:0];
NSLog(#"%d", didSetIcon);
[iconImage release];
}
case NSFileHandlingPanelCancelButton:
{
return;
}
}
}