NSOpenPanel reopening after selection - objective-c

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.

Related

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

Coredata - Backup and restore with NSOpenPanel not working

OSX Project:
Something strange is happening, hoping someone has a thought on the solution. I have a coredata project and I'm working on the backup/restore portion.
Initially I had hardcoded the file name and used the Applications file directory for the storage location - this all worked without an issue.
Next, I used NSOpenPanel to select the storage location. In this step, I used the same filename in the restore process - this worked without issue.
Last, I used NSOpenPanel to select the file to restore - this is the issue. I receive errors and the file is NOT opened.
Create backup method
NSOpenPanel* openDlg = [NSOpenPanel openPanel];
[openDlg setCanChooseFiles:NO];
[openDlg setCanChooseDirectories:YES];
[openDlg setAllowsMultipleSelection:NO];
NSArray *pathName;
if ( [openDlg runModal] == NSOKButton )
{
pathName = [openDlg URLs];
}
filePathNameBackup = [pathName objectAtIndex:0];
NSDateFormatter *format = [[NSDateFormatter alloc]init];
[format setDateFormat:#"yyyyMMddHHmmssSSS"];
NSString *stringOfDate = [format stringFromDate:[NSDate date]];
fileNameBackup = [fileNameBackup stringByAppendingString:stringOfDate];//fileNameBackup is defined earlier as "datafile"
fileNameBackup = [fileNameBackup stringByAppendingString:#".backup"];
//Created a filename with a timestamp
filePathNameBackup = [filePathNameBackup URLByAppendingPathComponent:fileNameBackup];
NSURL *urlbackup = filePathNameBackup;
...then the rest of the code to save the file - which does work
Then in the restore method I have the following:
NSOpenPanel* openDlg = [NSOpenPanel openPanel];
[openDlg setCanChooseFiles:YES];
[openDlg setCanChooseDirectories:NO];
[openDlg setAllowsMultipleSelection:NO];
[openDlg setAllowedFileTypes:[NSArray arrayWithObject:#"backup"]];
NSArray *pathName;
if ( [openDlg runModal] == NSOKButton )
{
pathName = [openDlg URLs];
NSURL *urlbackup = [pathname objectAtIndex:0];
... Then the rest of the restore method
The above does NOT work, I receive an error when creating the store - states it can not open file.
NSPersistentStore *restoreStore = [migrationCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:urlbackup options:nil error:nil];
Now the funny crazy part is if I use the file path name from the create backup method, it will work (filePathNameBackup):
NSOpenPanel* openDlg = [NSOpenPanel openPanel];
[openDlg setCanChooseFiles:YES];
[openDlg setCanChooseDirectories:NO];
[openDlg setAllowsMultipleSelection:NO];
[openDlg setAllowedFileTypes:[NSArray arrayWithObject:#"backup"]];
NSArray *pathName;
if ( [openDlg runModal] == NSOKButton )
{
pathName = [openDlg URLs];
NSURL *urlbackup = filePathNameBackup;
... Then the rest of the restore method
The above will work. I open the App, create a backup (Selecting the location in NSOpenPanel during the create backup method), change the file, save it, restore the backup, everything works!!
So why won't this work using NSOpenPanel to select the backup file?
If I NSLog the URL's, they both appear to be identical.
Summary of restore method:
NSOpenPanel* openDlg = [NSOpenPanel openPanel];
[openDlg setCanChooseFiles:YES];
[openDlg setCanChooseDirectories:NO];
[openDlg setAllowsMultipleSelection:NO];
[openDlg setAllowedFileTypes:[NSArray arrayWithObject:#"backup"]];
NSArray *pathName;
if ( [openDlg runModal] == NSOKButton )
{
pathName = [openDlg URLs];
NSURL *urlbackup = filePathNameBackup; //THIS WORKS (Use filename created during backup)
NSURL *urlbackup = [pathname objectAtIndex:0]; //THIS DOESNOT WORK
NO THEY BOTH ARE NOT BEING USED TOGETHER - I rem out one or the other urlbackup definitions before I run the program.
Again, why wont NSURL *urlbackup = [pathname objectAtIndex:0]; work?
Any thoughts would be appreciate, I was up late last night (this morning) and about ready to throw something. It just does not make any sense.
---[EDIT-----
The error received is error:14, unable to open database file
---[EDIT #2]----
Performed several more tests and I believe it has to do with sandboxing - as I00phole pointed out, just not sure how yet. If I hardcode a filename and use the app directory, all is good. If I hardcode another directory, it will not work.
I am not extremely familiar with sandboxing - any suggestions would be appreciated.

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