James Bucanek
James Bucanek

Reputation: 3439

NSSavePanel getting warning: "please start panels using NSSavePanel rather than NSApplication or NSWindow"

Running in macOS 10.15.6, built with Xcode 11.1, my app is suddenly (at least I just noticed) spitting out these warnings on the console when I present a save dialog:

WARNING: <NSSavePanel: 0x100e43250> found it necessary to prepare implicitly; please prepare panels using NSSavePanel rather than NSApplication or NSWindow.
WARNING: <NSSavePanel: 0x100e43250> found it necessary to start implicitly; please start panels using NSSavePanel rather than NSApplication or NSWindow.
WARNING: <NSSavePanel: 0x100e43250> running implicitly; please run panels using NSSavePanel rather than NSApplication.

The problem is, I am using NSSavePanel to present this dialog. Here's the entire method. I can't see what's wrong with it. I'm not using any deprecated methods. (In the case I'm having problems with, window is nil, so runModel gets called.)

/**  Present a modal dialog (window==nil) or begin a sheet (window!=nil) that prompts the user to create a new archive.
 *
 * Attaches the rundancy picker view to the save panel so the user can choose the redundancy level.
 * Presents a warning if the user picks a volume that has size limitations.
 * If successful, invokes the handler with the URL of the new repository and its creation settings.
 * @param window window for sheet, or nil for modal dialog
 * @param title optional title
 * @param name optional default name
 * @param directory optional default directory
 * @param handler completion handler
 */
+ (void)newArchivePrompForWindow:(nullable NSWindow *)window
                       withTitle:(nullable NSString*)title
                            name:(nullable NSString*)name
                     inDirectory:(nullable NSURL*)directory
               completionHandler:(void (^)(NSURL* repositoryURL, NSDictionary* settings))handler
{
    NSSavePanel* savePanel = [NSSavePanel savePanel];
    
    savePanel.title = ( title ?: @"New Archive" );
    savePanel.allowedFileTypes = @[kRepositoryFileType];
//  savePanel.canSelectHiddenExtension = YES;
    savePanel.extensionHidden = YES;
    savePanel.prompt = @"Create";
    savePanel.nameFieldLabel = @"Archive:";
    if (directory!=nil)
        savePanel.directoryURL = directory;     // set optional default folder
    if (name!=nil)
        savePanel.nameFieldStringValue = name;  // set optional name
    
    // attach the redundancy picker controller
    RepositoryPickRedundancyViewController* redundancyAccessoryController;
    redundancyAccessoryController = [[RepositoryPickRedundancyViewController alloc] initWithNibName:@"RepositoryPickRedundancyView"
                                                                                             bundle:nil];
    [savePanel setAccessoryView:redundancyAccessoryController.view];
    redundancyAccessoryController.version = kDataRedundancyPickerSchemeDefault;
    redundancyAccessoryController.configurationIndex = kDataRedundancyPickerConfigIndexDefault;
    
    // Present the panel
    if (window!=nil)
        {
        // The dialog is attached to a window
        // Present a sheet attached to the window
        [savePanel beginSheetModalForWindow:window completionHandler:^(NSInteger result) {
            if (result==NSFileHandlingPanelOKButton)
                // User picked an archive: vet it and continue
                NewArchivePostProcessing(savePanel,window,redundancyAccessoryController,savePanel.URL,handler);
            else
                // canceled
                handler(nil,nil);
            }];
        }
    else
        {
        // No parent window: run a modal dialog
        if ([savePanel runModal]==NSModalResponseOK)
            // User picked an archive: vet it and continue
            NewArchivePostProcessing(savePanel,nil,redundancyAccessoryController,savePanel.URL,handler);
        else
            // canceled
            handler(nil,nil);
        }
}

Anyone have a clue as to what's going on here?

Upvotes: 0

Views: 1294

Answers (1)

James Bucanek
James Bucanek

Reputation: 3439

If you replace

if ([savePanel runModal]==NSModalResponseOK)
    ...

with

[savePanel beginWithCompletionHandler:^(NSModalResponse result) {
    if (result==NSFileHandlingPanelOKButton)
        ...
    }];

The message goes away.

I'm guess it's a subtle way of trying to encourage the use of more modern APIs.

The only problem is, the message is wrong, runModal isn't deprecated, and there's no mention or documentation of this anywhere. Which seems to be par for the course, these days. :(

Upvotes: 2

Related Questions