为什么这个 AppleScript 空闲计时器没有正确触发?
Why is this AppleScript idle timer not triggering correctly?
我正在尝试创建一个计时器,它在特定时间(在本例中,每当时间为 xx:03:24)递增,并在达到用户输入的值时发送通知。一旦这样做,它会重置增量并重复直到手动退出。
但是,此代码无法按预期可靠地触发。有人猜到原因了吗?
on quit
continue quit
end quit
tell application "Notifications Scripting"
set event handlers script path to (path to me)
end tell
global actions, newActions
using terms from application "Notifications Scripting"
on notification activated
tell application "Safari"
activate
set winlist to every window
repeat with win in winlist
set numtabs to 0
try
set tablist to every tab of win
set numtabs to length of tablist
end try
if numtabs is greater than 0 then
repeat with t in tablist
if "fallenlondon.storynexus.com" is in (URL of t as string) then
tell application "System Events"
tell window id (id of win as integer) of application "Safari" to set current tab to tab (index of t as integer)
end tell
end if
end repeat
end if
end repeat
end tell
end notification activated
end using terms from
display dialog "How many actions do you want to build up before being notified?" default answer "1"
set actions to (text returned of result) as number
set newActions to 0
on idle
if ((seconds of (current date)) = 24) and ((minutes of (current date)) mod 10 = 3) then
set newActions to (newActions + 1)
set delayTime to 540
else
set delayTime to 0.5
end if
if newActions ≥ actions then
if newActions = 1 then
tell application "Notifications Scripting" to display notification "Fallen London" message "You have " & newActions & " new action!" sound name "Glass"
else
tell application "Notifications Scripting" to display notification "Fallen London" message "You have " & newActions & " new actions!" sound name "Glass"
end if
set newActions to 0
end if
return delayTime
end idle
我认为您的代码有一些问题。
首先要注意的是,只有 idle
处理程序中的代码会在每个空闲事件上被调用。换句话说,如果您希望脚本的主体 运行 每个空闲进程,它不会。
以此为例...
on run
display dialog "hello!" giving up after 3
end run
on idle
display dialog "Idle test!" giving up after 3
return 5
on idle
当您将上面的代码保存为 stay open
脚本时,您会看到一个显示 "hello" 的对话框,然后您会多次收到 "Idle test!" 消息,直到您退出脚本。 记得保存为"Stay Open"
要解决这个问题,如果您希望 idle
处理程序之外的所有代码都到 运行,请从它创建一个自定义函数,您可以从空闲处理程序调用它。
on yourCustomFunction()
-- All the code you want to run prior when the idle function is called
end yourCustomFunction
on idle
yourCustomFunction()
-- any other additional code you want to run here
return 5
end idle
还有一点我想指出。您不需要 tell application "Notifications Scripting"
,您可以 display notification
如下所示。
on idle
if ((seconds of (current date)) = 24) and ((minutes of (current date)) mod 10 = 3) then
set newActions to (newActions + 1)
set delayTime to 540
else
set delayTime to 0.5
end if
if newActions ≥ actions then
if newActions = 1 then
display notification "You have " & newActions & " new action!" with title "Fallen London" sound name "Glass"
else
display notification "You have " & newActions & " new actions!" with title "Fallen London" sound name "Glass"
end if
set newActions to 0
end if
return delayTime
end idle
最后,我建议添加一个 on run
处理程序,而不是在没有它的情况下只在脚本中编写代码。
我不希望您的 idle
实现可靠地工作。它不是一种精确的计时机制;因此以下假设是不合理的:
if ((seconds of (current date)) = 24) and ((minutes of (current date)) mod 10 = 3) then
您正在尝试在 10 分钟的循环中达到 1 秒 window,如果您错过了 window,您还需要 10 分钟才能尝试再次.
一个可靠的方法是存储一个表示下一次触发时间的日期,然后定期检查当前日期现在是否在那个日期之后触发,如果它确实:
to nextTriggerDate() -- returns next xx:x3:23 date
set d to current date
set {d's minutes, d's seconds} to {((d's minutes) div 10 * 10) + 3, 23}
if d < (current date) then set d to d + 10 * minutes
d
end nextTriggerDate
property _triggerDate : nextTriggerDate()
on idle
if (current date) > _triggerDate then
set _triggerDate to nextTriggerDate()
-- DO STUFF HERE...
end if
return 1
end idle
或者,您可以通过专为此类任务设计的 AppleScript-ObjC 桥使用 NSTimer
,或者将 launchd
脚本设置为 运行 AppleScript如果您不想绑定到保持打开的小程序,则在指定的时间。
我正在尝试创建一个计时器,它在特定时间(在本例中,每当时间为 xx:03:24)递增,并在达到用户输入的值时发送通知。一旦这样做,它会重置增量并重复直到手动退出。
但是,此代码无法按预期可靠地触发。有人猜到原因了吗?
on quit
continue quit
end quit
tell application "Notifications Scripting"
set event handlers script path to (path to me)
end tell
global actions, newActions
using terms from application "Notifications Scripting"
on notification activated
tell application "Safari"
activate
set winlist to every window
repeat with win in winlist
set numtabs to 0
try
set tablist to every tab of win
set numtabs to length of tablist
end try
if numtabs is greater than 0 then
repeat with t in tablist
if "fallenlondon.storynexus.com" is in (URL of t as string) then
tell application "System Events"
tell window id (id of win as integer) of application "Safari" to set current tab to tab (index of t as integer)
end tell
end if
end repeat
end if
end repeat
end tell
end notification activated
end using terms from
display dialog "How many actions do you want to build up before being notified?" default answer "1"
set actions to (text returned of result) as number
set newActions to 0
on idle
if ((seconds of (current date)) = 24) and ((minutes of (current date)) mod 10 = 3) then
set newActions to (newActions + 1)
set delayTime to 540
else
set delayTime to 0.5
end if
if newActions ≥ actions then
if newActions = 1 then
tell application "Notifications Scripting" to display notification "Fallen London" message "You have " & newActions & " new action!" sound name "Glass"
else
tell application "Notifications Scripting" to display notification "Fallen London" message "You have " & newActions & " new actions!" sound name "Glass"
end if
set newActions to 0
end if
return delayTime
end idle
我认为您的代码有一些问题。
首先要注意的是,只有 idle
处理程序中的代码会在每个空闲事件上被调用。换句话说,如果您希望脚本的主体 运行 每个空闲进程,它不会。
以此为例...
on run
display dialog "hello!" giving up after 3
end run
on idle
display dialog "Idle test!" giving up after 3
return 5
on idle
当您将上面的代码保存为 stay open
脚本时,您会看到一个显示 "hello" 的对话框,然后您会多次收到 "Idle test!" 消息,直到您退出脚本。 记得保存为"Stay Open"
要解决这个问题,如果您希望 idle
处理程序之外的所有代码都到 运行,请从它创建一个自定义函数,您可以从空闲处理程序调用它。
on yourCustomFunction()
-- All the code you want to run prior when the idle function is called
end yourCustomFunction
on idle
yourCustomFunction()
-- any other additional code you want to run here
return 5
end idle
还有一点我想指出。您不需要 tell application "Notifications Scripting"
,您可以 display notification
如下所示。
on idle
if ((seconds of (current date)) = 24) and ((minutes of (current date)) mod 10 = 3) then
set newActions to (newActions + 1)
set delayTime to 540
else
set delayTime to 0.5
end if
if newActions ≥ actions then
if newActions = 1 then
display notification "You have " & newActions & " new action!" with title "Fallen London" sound name "Glass"
else
display notification "You have " & newActions & " new actions!" with title "Fallen London" sound name "Glass"
end if
set newActions to 0
end if
return delayTime
end idle
最后,我建议添加一个 on run
处理程序,而不是在没有它的情况下只在脚本中编写代码。
我不希望您的 idle
实现可靠地工作。它不是一种精确的计时机制;因此以下假设是不合理的:
if ((seconds of (current date)) = 24) and ((minutes of (current date)) mod 10 = 3) then
您正在尝试在 10 分钟的循环中达到 1 秒 window,如果您错过了 window,您还需要 10 分钟才能尝试再次.
一个可靠的方法是存储一个表示下一次触发时间的日期,然后定期检查当前日期现在是否在那个日期之后触发,如果它确实:
to nextTriggerDate() -- returns next xx:x3:23 date
set d to current date
set {d's minutes, d's seconds} to {((d's minutes) div 10 * 10) + 3, 23}
if d < (current date) then set d to d + 10 * minutes
d
end nextTriggerDate
property _triggerDate : nextTriggerDate()
on idle
if (current date) > _triggerDate then
set _triggerDate to nextTriggerDate()
-- DO STUFF HERE...
end if
return 1
end idle
或者,您可以通过专为此类任务设计的 AppleScript-ObjC 桥使用 NSTimer
,或者将 launchd
脚本设置为 运行 AppleScript如果您不想绑定到保持打开的小程序,则在指定的时间。