import Foundation
import ServiceManagement
import os.log
@available(macOS 13.0, *)
public enum LaunchOnLogin {
public static var isEnabled: Bool {
get { SMAppService.mainApp.status == .enabled }
set {
do {
if newValue {
if SMAppService.mainApp.status == .enabled {
try? SMAppService.mainApp.unregister()
}
try SMAppService.mainApp.register()
} else {
try SMAppService.mainApp.unregister()
}
} catch {
os_log("Failed to \(newValue ? "enable" : "disable") launch at login: \(error.localizedDescription)")
}
}
}
}
import AppKit
import ServiceManagement
@available(macOS 13.0, *)
class LoginItemManager {
func loginItemIsEnabled() -> Bool {
return SMAppService.mainApp.status == .enabled
}
func disableLoginItem() {
try? SMAppService.mainApp.unregister()
}
func enableLoginItem() {
try? SMAppService.mainApp.register()
}
}
import ServiceManagement
public extension SMAppService {
var isEnabled: Bool {
status == .enabled
}
func toggle() throws {
isEnabled ? try unregister() : try register()
}
}
■ まとめ
以上を参考に、こう書きました。
@AppStorage("launchAtLogin") private var isOn = false
Toggle("Launch at login", isOn: $isOn)
.onAppear {
isOn = SMAppService.mainApp.status == .enabled
}
.onChange(of: isOn) {
let app = SMAppService.mainApp
try? isOn ? app.register() : app.unregister()
}
その後、結局、
@AppStorage も @State も持たないようにしました。
登録状態は、
[Settings] - [General] - [Login Items]
でOS側設定画面からも管理できます。
しかし、双方向のバインディングはつらくないですか。