Разрабатываемое командой приложение для строки меню macOS должно запускаться после входа пользователя в систему. На удалённом Mac вы включаете параметр «Запускать при входе», и приложение показывает, что он активен. Затем вы отключаетесь от удалённого рабочего стола, подключаетесь снова и обнаруживаете, что приложение всё это время работало. Это не доказывает, что объект входа работает. При проверке отдельно фиксируйте регистрацию, разрешение пользователя и запуск после нового входа в систему. В частности, не принимайте разрыв удалённого подключения за выход из учётной записи macOS.
Определите объект и границы проверки
Здесь проверяется объект входа основного приложения, зарегистрированный через SMAppService.mainApp, а не фоновый вспомогательный процесс или служба, запускаемая при загрузке системы. Приложение должно быть рассчитано на macOS 13 или новее и вызывать API регистрации из собственного процесса. Отдельный скрипт Swift, запущенный из командной строки, не может выполнить ту же регистрацию за приложение.
Подготовьте для проверки отдельную стандартную учётную запись и заранее убедитесь, что сможете повторно войти в её графический рабочий стол. Не проводите эксперимент под рабочей учётной записью, в которой выполняется сборка: выход завершит интерактивный сеанс и может прервать зависящие от него процессы. Прежде чем начать, сохраните работу и запишите способ повторного подключения.
«Зарегистрировано», «разрешено пользователем» и «запустилось после входа» — три разных вывода. Для каждого нужны свои подтверждения: одно состояние не доказывает следующее.
Проверьте установленное приложение
Проверяйте пакет приложения, который планируете поставить пользователям, а не только запуск из Xcode. Замените путь ниже фактическим расположением установленного приложения:
APP="/Applications/ExampleApp.app"
test -d "$APP" || { echo "App bundle not found"; exit 1; }
/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' \
"$APP/Contents/Info.plist"
codesign --verify --deep --strict --verbose=2 "$APP"
Запишите выведенный идентификатор пакета и сверьте его с проверяемой сборкой. Если проверка codesign не проходит, сначала исправьте пакет приложения: невозможность нормально запустить приложение не следует принимать за сбой объекта входа. Успешная проверка подписи также не подтверждает ни разрешение пользователя, ни запуск после входа.
Обрабатывайте состояние регистрации в приложении
Привяжите регистрацию к явному переключателю в настройках приложения, а не вызывайте её безусловно при каждом запуске. Разместите следующий код в целевом приложении macOS; вызывающий код должен преобразовывать возвращённое состояние в понятное сообщение интерфейса:
import ServiceManagement
@MainActor
func enableLaunchAtLogin() throws -> SMAppService.Status {
let service = SMAppService.mainApp
if service.status == .notRegistered {
try service.register()
}
return service.status
}
Показывать в интерфейсе, что запуск включён, можно только при состоянии .enabled. При .requiresApproval предложите пользователю проверить Системные настройки — не показывайте это состояние как сбой и не пытайтесь незаметно повторять регистрацию. Ошибки также передавайте на обработку интерфейсу. При выключении переключателя вызовите в приложении try SMAppService.mainApp.unregister(), а затем повторно прочитайте состояние; одного изменения вида переключателя недостаточно.
Проверьте разрешение пользователя
Под той же тестовой учётной записью откройте Системные настройки и найдите раздел, связанный с объектами входа. Проверьте, есть ли там приложение и требуется ли разрешить его вручную. Название раздела зависит от версии macOS, поэтому ориентируйтесь на интерфейс проверяемой системы. После разрешения вернитесь в приложение и снова прочитайте SMAppService.mainApp.status. Не записывайте, что автозапуск прошёл проверку, только потому, что название приложения появилось в Системных настройках.
Выполните новый вход в систему
Сначала завершите работу приложения обычным способом и зафиксируйте, что оно больше не запущено. Затем через меню macOS явно выйдите из тестовой учётной записи и снова войдите в её графический рабочий стол. Проверьте наличие окна приложения, значка в строке меню или другого состояния, по которому можно подтвердить его работу. Заранее договоритесь, какой именно признак считать успешным запуском, чтобы не засчитать приложение, которое сразу после запуска аварийно завершилось.
| Этап проверки | Что сохранить в качестве подтверждения |
|---|---|
| До регистрации | Версия приложения, идентификатор пакета, тестовая учётная запись |
| После регистрации | Состояние объекта входа, прочитанное приложением |
| После разрешения | Состояние в Системных настройках и повторно прочитанное приложением состояние |
| После повторного входа | Работает ли приложение и можно ли нормально с ним взаимодействовать |
| После отключения и ещё одного входа | Приложение не запустилось автоматически через этот объект входа |
Последнюю строку проверяйте после отключения объекта входа из самого приложения. Если приложение запускается и другими способами, сначала определите их: одно лишь наличие процесса не опровергает результат проверки отключения. По завершении проверки при необходимости снова включите объект входа и убедитесь, что переключатель показывает нужное состояние.
Исключите ложные результаты из-за удалённого сеанса
Закрытие клиента удалённого рабочего стола, кратковременный обрыв сети или блокировка экрана не обязательно завершают сеанс пользователя macOS. Если после повторного подключения видно прежнее окно, обычно это означает лишь то, что сеанс продолжался, а не то, что сработал объект входа. Запуск приложения через SSH тоже не проверяет вход в графическую среду: окружение SSH-оболочки отличается от окружения сеанса рабочего стола.
Если состояние регистрации верное, но после входа приложение не появилось, проверяйте по порядку: вошли ли вы под той же учётной записью, из которой его зарегистрировали; проверяете ли установленный пакет, а не другую копию сборки; не требуется ли по-прежнему разрешение в Системных настройках; не запустилось ли приложение с последующим немедленным завершением. Если приложение ведёт журнал запуска, сопоставьте время события со временем этого входа, чтобы различить случаи «не запустилось» и «запустилось, но завершилось с ошибкой». Не записывайте в журнал учётные данные для доступа.
Сохраните результаты для следующей сборки
Оставьте краткую запись: версия приложения, идентификатор пакета, версия macOS, тестовая учётная запись, состояние до и после регистрации, действие по выдаче разрешения, результат повторного входа и результат повторной проверки после отключения. После каждого обновления пакета приложения как минимум повторно проверьте, что установлен нужный пакет, и выполните новый вход. Если менялась реализация объекта входа, заново пройдите проверку регистрации и отключения.
Цель этой процедуры — не доказать, что на конкретном компьютере приложение «всегда будет запускаться автоматически», а сделать поведение конкретной сборки воспроизводимым и пригодным для диагностики. Если отделять вход в графическую среду от удалённого подключения, причину неполадок с объектом входа обычно удаётся свести к пакету приложения, разрешению пользователя или запуску самого приложения.
Часто задаваемые вопросы
Почему приложение не запускается, хотя регистрация прошла успешно?
Проверьте, требуется ли разрешение пользователя, тестируется ли установленное приложение и был ли выполнен настоящий выход с новым входом в графическую сессию. Также проверьте, не завершается ли приложение сразу после запуска.
Можно ли заменить выход из системы отключением удалённого рабочего стола?
Нет. После отключения клиента сессия пользователя macOS может продолжать работать. Явно выйдите из тестовой учётной записи и войдите в её графическую сессию снова.
Подключите облачный Mac к своему рабочему процессу
VPSPush предоставляет выделенные физические Mac с удалённым доступом. Выберите локацию и срок аренды, затем проверьте данные для подключения и итоговую сумму в заказе.