BRZ Podcast Banner

как я боролся с AppleScript и iSync

Предыстория
iSync — программа для синхронизации адресной книги, календаря с телефоном. Мне, если честно, надоело открывать iSync и руками синхронизировать все с телефоном.
Задача
написать приложение/скрипт/workflow, который бы автоматически проводил синхронизацию. Идеальный вариант — синхронизация после внесения изменений в iCal/AddressBook
Решение
для реализации был выбран AppleScript. Алгоритм работы такой:
  1. внесены изменения в календарь/адресную книгу
  2. запускается iSync
  3. синхронизируется с телефоном (BT включен всегда)
  4. iSync закрывается
сразу же возникла проблема — как следить за изменениями в календаре? поскольку на первый взгляд простых инструментов для отслеживания нет, пришлось остановиться на закрытии приложения календаря.
проблема номер два — iSync не имеет команды для синхронизации с телефоном, есть только команда синхронизации баз. выход — имитировать нажатие сочетания клавиш при активном окне приложения.
проблема номер три — не понятно, как отслеживать процесс синхронизации (закончился или нет).
Был вариант написать Always Run приложение (эдакий AppleScript-сервер), который бы слушал события iCal и активизировал функцию синхронизации. при первом рассмотрении варинант отпал, так как конструкция
on quit application "iCal"
  -- some code here
end quit
не работала корректно — перехватывалось события выхода приложения сервера.
раз уж так все плохо, то решено было написать workflow для Automator и встроить его вызов в Finder (реализация претендует на звание сверхизвращенной).
код, вызывающий iSync и имитирующий нажатие кнопки:
tell application "iSync"
  activate
end tell

tell application "System Events"
  if UI elements enabled then
    tell process "iSync"
      set frontmost to true
    end tell
  -- iSync doesn't have a command to sync with device, so gettin' tricky with it
    keystroke "t" using command down
    keystroke return
  end if
end tell
далее был открыт Automator, и создан workflow из одного блока — выполнение AppleScript, который потом был встроен в контекстное меню Finder'a.
Листинг скрипта в Automator
on run {input, parameters}
-- routine that forces iSync to sync with cell phone
  tell application "iSync"
    (activate)
    (synchronize)
  end tell

  tell application "System Events"
    if UI elements enabled then
      tell process "iSync"
        set frontmost to true
      end tell
-- iSync doesn't have a command to sync with device, so gettin' tricky with it
      keystroke "t" using command down
      keystroke return
    end if
    delay 30
    quit application "iSync"
  end tell
return input
end run
Задача оказалась решена, но не с блеском. Если Вы знаете более элегантное решение — отпишитесь в комментарии.