Script runs in "Script Editor" but not in SD7


The script below runs in “Script Editor” but not in “Script Debugger.” In SD7 it just hangs with a spinning cursor. It does use “AppKit” and I know “Script Debugger” has more problems with “AppKit” than does “Script Editor.” So there may be nothing that can be done about it. The actual script allows multiple fields to be used for input as shown in the image below.

I included a sample of SD7 from “Activity Monitor” while it was hung.


-- Created 2017-09-23 by Takaaki Naganoya
-- 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property windisp : false
property wController : false

set fieldList to {"field 1", "field 2", "field 3", "field 4", "field 5", "field 6", "field 7", "field 8", "field 9", "field 10"}
--set fieldList to {"field 1", "field 2"}
set aButtonMSG to "OK"
set aWinTitle to "Multiple Text Field Input"
set aVal to getMultiTextFieldValues(fieldList, aWinTitle, aButtonMSG, 180) of me

on getMultiTextFieldValues(fieldList, aWinTitle, aButtonMSG, timeOutSecs)
	set (my windisp) to false
	set fLen to (length of fieldList) + 1
	set aView to current application's NSView's alloc()'s initWithFrame:(current application's NSMakeRect(0, 0, 360, (20 * fLen)))
	set a1y to (30 * fLen)
	set tList to {}
	repeat with i in fieldList
		set a1TF to (current application's NSTextField's alloc()'s initWithFrame:(current application's NSMakeRect(60, a1y, 80, 20)))
		(a1TF's setEditable:false)
		(a1TF's setStringValue:(i as string))
		(a1TF's setDrawsBackground:false)
		(a1TF's setBordered:false)
		set a2TF to (current application's NSTextField's alloc()'s initWithFrame:(current application's NSMakeRect(140, a1y, 200, 20)))
		(a2TF's setEditable:true)
		(a2TF's setDrawsBackground:true)
		(a2TF's setBordered:true)
		(aView's addSubview:a1TF)
		(aView's addSubview:a2TF)
		set the end of tList to a2TF
		set a1y to a1y - 30
	end repeat
	--Make Button
	set bButton to (current application's NSButton's alloc()'s initWithFrame:(current application's NSMakeRect(110, 10, 180, 40)))
	bButton's setButtonType:(current application's NSMomentaryLightButton)
	bButton's setBezelStyle:(current application's NSRoundedBezelStyle)
	bButton's setTitle:aButtonMSG
	bButton's setTarget:me
	bButton's setAction:("clicked:")
	bButton's setKeyEquivalent:(return)
	aView's addSubview:bButton
	aView's setNeedsDisplay:true
	--I tried making NSWindowController
	set aWin to (my makeWinWithView(aView, 400, ((fLen + 1) * 30), aWinTitle))
	set wController to current application's NSWindowController's alloc()
	wController's initWithWindow:aWin
	set (my windisp) to true
	wController's showWindow:me
	set aCount to timeOutSecs * 10
	set hitF to false
	repeat aCount times
		if (my windisp) = false then
			set hitF to true
			exit repeat
		end if
		delay 0.1
		set aCount to aCount - 1
	end repeat
	my closeWin:aWin
	if hitF = true then
		set aResList to {}
		repeat with i in tList
			set the end of aResList to (i's stringValue()) as string
		end repeat
		return false
	end if
	return aResList
end getMultiTextFieldValues

on clicked:aSender
	set (my windisp) to false
end clicked:

--make Window for Display
on makeWinWithView(aView, aWinWidth, aWinHeight, aTitle)
	set aScreen to current application's NSScreen's mainScreen()
	set aFrame to {{0, 0}, {aWinWidth, aWinHeight}}
	set aBacking to current application's NSTitledWindowMask
	set aDefer to current application's NSBackingStoreBuffered
	-- Window
	set aWin to current application's NSWindow's alloc()
	(aWin's initWithContentRect:aFrame styleMask:aBacking backing:aDefer defer:false screen:aScreen)
	aWin's setTitle:aTitle
	aWin's setDelegate:me
	aWin's setDisplaysWhenScreenProfileChanges:true
	aWin's setHasShadow:true
	aWin's setIgnoresMouseEvents:false
	aWin's setLevel:(current application's NSNormalWindowLevel)
	aWin's setOpaque:false
	aWin's setReleasedWhenClosed:true
	aWin's |center|()
	aWin's setContentView:aView
	return aWin
end makeWinWithView

--close win
on closeWin:aWindow
	repeat with n from 10 to 1 by -1
		(aWindow's setAlphaValue:n / 10)
		delay 0.02
	end repeat
	aWindow's |close|()
end closeWin:

Sample of Script (21.5 KB)

Let me clarify that a bit. Script Debugger doesn’t have any more problems with AppKit than Script Editor. Where it does have more problems is with code that is meant to be run only on the main thread (which is of course a lot of AppKit).

Your script includes a lot of code that should be performed on the main thread. if you want to run that in Script Debugger, you have to put it in handlers and call if via performSelectorOnMainThread:withObject:waitUntilDone:. You should also do the same in Script Editor, unless you hold down the control key and use Run in Foreground.

In reality, ignoring this sometimes works. But it’s a gamble, for a couple of reasons. One is that it can be OS version dependent: what works on one version can crash and burn on another. The other is that you’re potentially causing corruption that can result in inexplicable errors in seemingly unrelated code later on.

FWIW, it’s probably not a bad idea when writing and testing code that is thread-dependent to regularly quit and relaunch editor.


When working with AppKit I do all the coding in Script debugger. Then when it is time to test the code I copy the code in SD and paste it into “Script Editor” and I run it in “Script Editor.” Then when “Script Editor” gets messed up I quit it and restart. Once you get used to it it’s not that distracting.

Some of the things that go wrong with App kit do not seem like it would be AppKit related but quitting Script Editor and restarting causes the code to work.

Once the code is worked out and I run it from an Applet it works fine. In the end it is better to regularly restart the editor running AppKit code because some of the problems absolutely look like an AppleScript problem when the editor just needs to be restarted.

Quitting and restarting SD often is too distracting.

Now all we need is a Script Debugger that runs in it’s own process :slight_smile: But in all seriousness SD7 is a great update. I really like “Resources Tab” it was a pain to do ll that stuff manually before. The Enhanced Applet is a huge work saver and I too really like the new SD icon :slight_smile: