Как приложение синхронизации Mac OS X может отслеживать файлы

Мне интересно, как Timing может узнать количество времени, которое вы тратите в определенном файле. Я понимаю, что для этого требуется разрешение на доступ, но после этого, как он может обнаруживать, что в настоящее время на экране, плюс доступ к пути к данному файлу. Например, я интригую, что он знает, что я нахожусь на Xcode, но как он знает, что я работаю над конкретным файлом внутри Xcode?

Ответ 1

Я не работаю над Timing, поэтому я могу только рассказать о том, как их приложение было реализовано.

Сроки утверждают, что отслеживают три основных точки данных: используемые вами приложения, посещаемые вами веб-сайты и документы, которые вы редактируете.

Для приложений Timing, вероятно, прослушивает уведомление NSWorkspaceDidLaunchApplicationNotification, которое содержит информацию о только что запущенном приложении. Чтобы проверить открытые приложения в момент запуска Timing, он, вероятно, проверяет нефоновые процессы из System Events, возможно, так:

osascript -e 'tell application "System Events" to get name of (processes where background only is false)'

(Источник Получить список запущенных приложений в Mac OS X в Bash?)

Для истории Timing может использовать API истории HTML5 с Safari (я не знаю, какие браузеры Timing заявляют о поддержке этой функции), или используйте подход Charles Proxy и отслеживайте входящие и исходящие пакеты и запросы. Реализация может различаться в зависимости от того, требует ли Timing права администратора.

Для документов Timing может использовать команду lsof как Droppy, предложенную в их комментарии, или она может использовать один из интерфейсов Apple. Pre-El Capitan, Apple опубликовал последние документы в файле plist по пути ~/Library/Preferences/com.apple.recentitems.plist. В версиях macOS, более новых, чем El Capitan, вы можете использовать команду mdfind и указать значение kMDItemContentModificationDate для поиска файлов, измененных между двумя датами:

mdfind -onlyin $HOME '((kMDItemContentModificationDate > $time.now(-60m)) && (kMDItemContentModificationDate < $time.now()))' | grep -v /Library/

(Источник Alfred)