Добавить функциональность «Запустить в входе в систему» в приложение MacOS в секундах
Если ваше приложение предназначено для MacOS 13 или более поздней версии, вместо этого ознакомьтесь с этой современной версией.
Обычно это довольно запутанный и подверженная ошибкам процесс, чтобы добавить это (на MacOS 12 и старше). Больше не надо!
Этот пакет работает как с приложениями для песочниц, так и с не-сандбоками, а также его приложений, совместимых с приложениями, и используется в таких приложениях, как Plash, Dato, Lungo и индикатор батареи.
В этом пакете используется новый SMAppService на MacOS 13+ и SMLoginItemSetEnabled на старых версиях macOS.
SMAppService существует?MacOS 10.13+
Добавьте https://github.com/sindresorhus/LaunchAtLogin-Legacy на вкладке «Swift Package Manager» в Xcode.
Пропустите этот шаг, если ваше приложение предназначено для MacOS 13 или более поздней версии.
Добавьте новый «Фаза сценария запуска» ниже (не в) «Копировать ресурсы пакета» в «фазы сборки» со следующим:
" ${BUILT_PRODUCTS_DIR} /LaunchAtLogin_LaunchAtLogin.bundle/Contents/Resources/copy-helper-swiftpm.sh "И снять «на основе анализа зависимостей».
Фаза сборки не может работать с включенным «Санчанка пользователя сценария». С XCODE 15 или более новым, где он включен по умолчанию, отключите «песочницы с скриптом пользователя» в настройках сборки.
(Нужно несколько дополнительных работ, чтобы сделать наш сценарий, чтобы соответствовать песочнице фазы сборки.) (Я бы назвал Copy “Launch at Login Helper” )
Не нужно хранить какое -либо состояние для пользователей.
Обратите внимание, что руководящие принципы Mac App Store требуют, чтобы функциональность «запустить в входе в систему» была включена в ответ на действие пользователя. Обычно это решается, что делает его предпочтением, которое отключено по умолчанию. Многие приложения также позволяют пользователю активировать его на желанном экране.
import LaunchAtLogin
print ( LaunchAtLogin . isEnabled )
//=> false
LaunchAtLogin . isEnabled = true
print ( LaunchAtLogin . isEnabled )
//=> true Этот пакет поставляется с просмотром LaunchAtLogin.Toggle , который похож на встроенный Toggle , но с предопределенным связыванием и меткой. Нажав на представление, переключает «запуск в входе в систему» для вашего приложения.
struct ContentView : View {
var body : some View {
LaunchAtLogin . Toggle ( )
}
} Этикетка по умолчанию - "Launch at login" , но он может быть переопределен для локализации и других потребностей:
struct ContentView : View {
var body : some View {
LaunchAtLogin . Toggle {
Text ( " Launch at login " )
}
}
} В качестве альтернативы, вы можете использовать LaunchAtLogin.observable в качестве привязки с @ObservedObject :
import SwiftUI
import LaunchAtLogin
struct ContentView : View {
@ ObservedObject private var launchAtLogin = LaunchAtLogin . observable
var body : some View {
Toggle ( " Launch at login " , isOn : $launchAtLogin . isEnabled )
}
} Просто подпишитесь на LaunchAtLogin.publisher :
import Combine
import LaunchAtLogin
final class ViewModel {
private var isLaunchAtLoginEnabled = LaunchAtLogin . isEnabled
private var cancellables = Set < AnyCancellable > ( )
func bind ( ) {
LaunchAtLogin
. publisher
. assign ( to : . isLaunchAtLoginEnabled , on : self )
. store ( in : & cancellables )
}
} Используйте LaunchAtLogin.publisher.values .
Свяжите контроль с свойством LaunchAtLogin.kvo :
import Cocoa
import LaunchAtLogin
final class ViewController : NSViewController {
@ objc dynamic var launchAtLogin = LaunchAtLogin . kvo
} 
На MacOS 12 и ранее пакет объединяет вспомогательное приложение, необходимое для запуска вашего приложения, и копирует его в ваше приложение во время сборки. На MacOS 13 и позже он называет встроенный API.
Пожалуйста, убедитесь, что этап сценария запуска запускаетлогина по -прежнему находится ниже фазы «встроенных фреймворков». Заказ мог быть случайно изменен.
Ошибка сборки обычно представляет собой:
cp: […]/Resources/LaunchAtLoginHelper.app: No such file or directory
rm: […]/Resources/copy-helper.sh: No such file or directory
Command PhaseScriptExecution failed with a nonzero exit code
К сожалению, это ожидаемое поведение.
Тем не менее, он покажет там на MacOS 13 и позже.
Обычно это вызвано тем, что одна или несколько более старых сборки вашего приложения лежат где -то в системе, и вместо этого MacOS выбирает одну из них, у которого нет помощника запуска, и, следовательно, не начинается.
Некоторые вещи вы можете попробовать:
DerivedData .Некоторые полезные ответы на переполнение стека:
LaunchAtLogin.bundle я не вижу, чтобы запустить ошибку нотаризации для распределения идентификаторов разработчикаКак обсуждалось здесь, этот пакет пытается определить, делаете ли вы выпуск или отладочный сборник и соответствующим образом очистите его установку. Если в вашей сборке отладки отсутствует пакет или, наоборот, в вашей сборке релиза есть комплект, и это вызывает ошибку подписания кода, это означает, что это не удалось.
Определение сценария основано на флаге «только активная архитектура» в настройках сборки. Если это установлено на YES , то скрипт будет упаковать запуск для сборки отладки. Вы должны установить этот флаг на NO , если планируете распространять сборку с помощью CodeSigning.