1

I’m trying present an alert as a sheet using JXA. It works as expected in AppleScript, but when running the equivalent JavaScript the sheet never dismisses.

To reproduce, run this in Automator with the “Run AppleScript” workflow:

use framework "Cocoa"
 
on show(title as string, msg as string)
    set alert to current application's NSAlert's new()
    tell alert
        its setMessageText:title
        its setInformativeText:(msg)
        its beginSheetModalForWindow:(current application's NSApp's mainWindow()) completionHandler:(missing value)
    end tell
end show
 
show("test", "test")

Then try running this in a different workflow with “Run JavaScript”:

ObjC.import("Cocoa");
 
function show(title, msg) {
    let alert = $.NSAlert.new;
    alert.messageText = title;
    alert.informativeText = msg;
    alert.beginSheetModalForWindowCompletionHandler($.NSApp.mainWindow, null);
}
 
show("test", "test");

Is there a step I'm missing here? In the docs for beginSheetModalForWindow:completionHandler:, it states:

Note that orderOut: no longer needs to be called in the completion handler. If you don’t dismiss the alert, it will be done for you after the completion handler finishes.

https://developer.apple.com/documentation/appkit/nsalert/1524296-beginsheetmodalforwindow

I'm running the latest version of macOS at the time of this writing, 11.1.

1 Answers1

1

No completion handler, no need beginSheetModalForWindow:completionHandler: method. Use runModal: instead. Save following JXA code as application and run it.

ObjC.import("Cocoa");
 
function show(title, msg) {
    let alert = $.NSAlert.new;
    alert.messageText = title;
    alert.informativeText = msg;
    alert.runModal;
}
 
show("test", "test");

Using both methods together also works without throwing an error.

ObjC.import("Cocoa");
 
function show(title, msg) {
    let alert = $.NSAlert.new;
    alert.messageText = title;
    alert.informativeText = msg;
    alert.beginSheetModalForWindowCompletionHandler($.NSApp.mainWindow, null);
    alert.runModal;
}
 
show("test", "test");

Here is AppleScript Objective C application example which uses completion handler and 2 methods together. The same can be done with JavaScript Objective C.

use framework "Cocoa"
use scripting additions

on show(title as string, msg as string)
    set alert to current application's NSAlert's new()
    tell alert
        its setMessageText:title
        its setInformativeText:(msg)
        its beginSheetModalForWindow:(current application's NSApp's mainWindow()) completionHandler:(my completionHandler())
        its runModal()
    end tell
end show

on completionHandler()
    repeat 5 times
        display dialog (time string of (current date)) giving up after 1
        delay 1
    end repeat
end completionHandler

show("test", "test")
Robert Kniazidis
  • 1,760
  • 1
  • 7
  • 8