FSEvents: Разбираемся с мониториногом событий файловой системы в macOS
Механизм FSEvents состоит из трёх базовых частей:
Изначально информация о событиях хранится в памяти. Когда происходит событие, ему назначается 64-битный идентификатор. Может получиться так что событие пришло с уже назначенным идентификатором, в этом случае, просто обновятся флаги. После того, как буфер памяти заполнится события записываются на диск.
Подписываемся на события программно
Если тебя больше интересует возможность подписаться на события и слушать их программно, то предлагаю реализовать для этого несложный класс, который будет подписываться на уведомления в заданной директории и возвращать информацию об изменениях (путь к файлу и флаги изменений) в колбек.
Подписываемся на поток событий файловой системы
Откроем Xcode и создадим новый проект, это будет Cocoa App (на вкладке macOS), язык выберем Swift. Создадим новый класс (File > New > File > macOS > Swift file) под названием FSEventsService и напишем следующий код:
Здесь мы просто объявили класс и создали несколько переменных. Теперь нам нужно запустить мониторинг событий, для этого определим следующий метод:
Теперь осталось создать поток событий и передать в него необходимую информацию, а именно:
После этого остаётся только добавить поток событий в RunLoop (часть инфраструктуры отвечающая за обработку асинхронных событий, приходящих в поток) и запустить мониторинг.
Обрабатываем полученные события
Реализация колбэка будет выглядеть так:
Здесь мы получаем экземпляр нашего класса из контекста и записываем его в переменную mySelf. Из нее извлекаем колбек, который мы передали при инициализации нашего класса, пробегаем в цикле по пришедшим событиям, в нём создаем структуру, которая содержит информацию о событии (идентификатор события, путь и флаги) и передаем ее в этот коллбек.
Структура с информацией о событии выглядит следующим образом:
Останавливаем получение событий
Здесь все достаточно просто: нужно вызвать несколько методов для остановки потока событий:
Вызов этого метода можно добавить, например, в deinit :
Использование класса
На этом написание простейшей обёртки закончено, мы теперь легко можем получить события от файловой системы, например:
После запуска в логе приложения можно будет увидеть строки с измененными файлами. Перед запуском нужно не забыть отключить Sandbox (выбрать проект в инспекторе слева, перейти на вкладку Capabilities, отключить App Sandox), иначе у приложения будет доступ к файловой системе только внутри песочницы.
Фильтрация событий
В результате работы нашего класса, мы получили флаг события, который представляет собой битовую маску. Apple заранее определила определила для нас костанты с флагами, соотвествующими опредлённому типу события. Например, если мы захотим отфильтровать только события с созданием файла, это будет выглядеть следующим образом:
Подбирая комбинации флагов, можно гибко настроить получаемый поток событий под собственные нужды. Полный список флагов можно найти в документации.
Заключение
Сегодня мы рассмотрели реализацию собственной обертки над API FSEvents, если не считать взаимодействие с API на C, то использовать из Swift его довольно просто и не должно вызвать затруднений. На GitHub можно найти большое количество библиотек, схожих с тем, что мы реализовали сегодня. Пользоваться ими или нет, нужно решать исходя из конкретных задач: с одной стороны зачем писать лишний boilerplate, когда кто-то его уже написал за тебя, а с другой стороны в сложных решениях, всё равно приходится разбираться с внутренним устройством библиотек и докручивать их под специфичные нужды заказчика, так что может быть имеет смысл написать такой класс с нуля.
System Events Класс
Определение
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Предоставляет доступ к уведомлениям о системных событиях. Этот класс не наследуется.
Примеры
Этот раздел содержит два примера. в первом примере показано, как использовать системные события в обычном приложении, а во втором примере показано, как использовать системные события в службе Windows.
Пример 1
Следующий пример кода регистрирует интерес в некоторых системных событиях, а затем ожидает возникновения какого-либо из этих событий. Отображаемые выходные данные происходят, если пользователь изменяет разрешение экрана.
Пример 2
Службы не имеют циклов сообщений, если только им не разрешено взаимодействовать с рабочим столом. Если цикл обработки сообщений не предоставлен скрытой формой, как в этом примере, служба должна запускаться под локальной системной учетной записью, а для включения взаимодействия с рабочим столом требуется вмешательство вручную. То есть администратор должен вручную установить флажок Разрешить взаимодействие со службой «Рабочий стол » на вкладке » Вход » диалогового окна «Свойства службы». В этом случае цикл обработки сообщений предоставляется автоматически. Этот параметр доступен, только если служба запущена под локальной системной учетной записью. Взаимодействие с рабочим столом не может быть включено программным способом.
Чтобы запустить пример, выполните следующие действия.
Скомпилируйте код из командной строки. Имя, используемое для исходного файла, не имеет значения.
Используйте консоль служб для запуска службы.
Измените системное время или измените параметры пользователя, например свойства мыши.
Просмотрите сообщения в категории » приложение » Просмотр событий.
Используйте консоль служб для завершения работы службы.
Комментарии
SystemEventsКласс предоставляет возможность реагирования на определенные типы системных событий.
При возникновении системного события все делегаты, прикрепленные к событию, вызываются с помощью потока, отслеживающего системные события. Таким образом, следует делать любые вызовы из обработчиков событий, которые являются потокобезопасными. Если необходимо вызвать системное событие, которое не представлено в качестве члена этого класса, можно использовать InvokeOnEventsThread метод.
Не следует выполнять длительную обработку потока, вызывающего обработчик системных событий, поскольку это может препятствовать функционированию других приложений.
некоторые системные события могут не возникать в Windows Vista. убедитесь, что приложение работает правильно в Windows Vista.
Методы
Создает новый таймер окна, связанный с окном системных событий.
Определяет, равен ли указанный объект текущему объекту.
Служит хэш-функцией по умолчанию.
Возвращает объект Type для текущего экземпляра.
Вызывает заданный делегат, используя поток, прослушивающий системные события.
Завершает работу таймера, заданного идентификатором.
Создает неполную копию текущего объекта Object.
Возвращает строку, представляющую текущий объект.
События
Происходит, когда пользователь изменяет параметры дисплея.
Происходит при изменении параметров дисплея.
Происходит перед завершением потока, прослушивающего системные события.
Происходит, когда пользователь добавляет шрифты в систему или удаляет шрифты из системы.
Происходит при недостатке оперативной памяти в системе.
Происходит, когда пользователь переходит к приложению, которое использует другую палитру.
Происходит, когда пользователь приостанавливает или возобновляет работу системы.
Происходит, когда пользователь выходит из системы или завершает ее работу.
Происходит, когда пользователь пытается выйти из системы или завершить ее работу.
Происходит после смены текущего вошедшего в систему пользователя.
Происходит, когда пользователь изменяет время системных часов.
Происходит, когда заканчивается интервал таймера Windows.
Происходит после изменения пользовательских параметров.
Происходит при изменении пользовательских параметров.
System Events: What Is It?
Mac Convert for Life
Mikuro
Crotchety UI Nitpicker
System Events controls Folder Actions (which are AppleScripts you can attach to folders so that they’ll run whenever the folder is opened or an item is added/removed from it, etc.).
It can also be used by AppleScript developers to do some very basic and useful things like managing files, getting information on running applications, and controlling interface elements by simulating keyboard/mouse actions. It’s a scripter’s best friend.
Mac Convert for Life
System Events controls Folder Actions (which are AppleScripts you can attach to folders so that they’ll run whenever the folder is opened or an item is added/removed from it, etc.).
It can also be used by AppleScript developers to do some very basic and useful things like managing files, getting information on running applications, and controlling interface elements by simulating keyboard/mouse actions. It’s a scripter’s best friend.
Thanks, Mikuro, for your reply. But now I have a couple more questions:
1. How did it get there (in my start-up items) if I didn’t put it there? I’m the only one who uses my iBook.
2. Should I delete it or uncheck it from launching/running upon startup or just leave it as is?
I never saw this before and now, suddenly, it’s there. It’s unsettling.
Использование Tab для переключения между кнопками
![]() | ||
![]() | |
![]() |
![]() |












