0

I am trying to create a timer that increments at a certain time (in this case, whenever the time is xx:03:24) and sends a notification when it reaches a user-inputted value. Once it does so, it resets the increment and repeats until manually quit.

However, this code is not reliably triggering when it is supposed to. Does anyone have a guess as to why?

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
4

2 回答 2

0

我认为你的代码有一些对你不利的事情。

首先要注意的是,只有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脚本时,您会看到一个对话框,上面写着“你好”,然后您会看到“空闲测试!” 消息多次,直到您退出脚本。记得把它保存为“保持开放”

要解决此问题,如果您希望处理程序之外的所有代码都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处理程序,而不是在没有它的情况下在脚本中编写代码。

于 2016-07-19T05:05:00.990 回答
0

我不希望您的idle实现能够可靠地工作。它不是一个精确的计时机制;因此,以下假设是不可靠的:

if ((seconds of (current date)) = 24) and ((minutes of (current date)) mod 10 = 3) then

您在这里尝试在 10 分钟的循环中点击 1 秒的窗口,如果您错过了该窗口,则需要再过 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

或者,您可以NSTimer通过专为此类任务设计的 AppleScript-ObjC 桥接器使用,或者launchd如果您不想被绑定到保持打开的小程序,则可以设置脚本以在指定时间运行 AppleScript .

于 2016-07-24T21:44:07.830 回答