🍁
Swift: macOS 13以降でのLaunch At Loginの実装
macOS 13からServiceManagement
が強化されSMAppService
が追加されたことで、ようやくヘルパーアプリに頼らずにログイン項目にアプリを登録できるようになりました。🎉(ヘルパーではなくアプリ本体がログイン項目に登録され、ログイン時に起動するようにできます。)しかも、実装方法もかなりシンプルでわかりやすいAPIとなっております。
実装例
import SwiftUI
import ServiceManagement
struct ContentView: View {
@State var launchAtLogin: Bool
init() {
self.launchAtLogin = SMAppService.mainApp.status == .enabled
}
var body: some View {
VStack {
Toggle("launch at login", isOn: $launchAtLogin)
.onChange(of: launchAtLogin) { [oldValue = launchAtLogin] newValue in
do {
if newValue {
try SMAppService.mainApp.register()
} else {
try SMAppService.mainApp.unregister()
}
} catch {
Swift.print(error.localizedDescription)
}
if newValue != (SMAppService.mainApp.status == .enabled) {
launchAtLogin = oldValue
}
}
}
}
}
ポイント
-
SMAppService.mainApp.status
で現状ログイン項目に入っているのかどうかが判断できます。 -
SMAppService.mainApp.register()
でログイン項目に登録できます。(try
がついていますがどんな時にこれが失敗するのか謎です。) -
SMAppService.mainApp.unregister()
でログイン項目から登録解除できます。環境設定から手動で登録解除しているのに、さらにその状態からunregister()
を叩くとError
がthrow
されます。 -
.onChange(of: flag) { [oldValue = flag] newValue in }
のようにトグルを管理するflag
をクロージャーでキャプチャーすることで、古い値を参照できます。設定が更新できなかった際にトグルの状態を正常に戻すためにoldValue
が必要です。
参考
Discussion
macOS 12までのLaunch At Loginの実装(SwiftUI編)