Skip to content

feat: add Launch at Login toggle using SMAppService - #63

Merged
jatinkrmalik merged 3 commits into
mainfrom
feat/launch-at-login
Mar 12, 2026
Merged

feat: add Launch at Login toggle using SMAppService#63
jatinkrmalik merged 3 commits into
mainfrom
feat/launch-at-login

Conversation

@jatinkrmalik

@jatinkrmalik jatinkrmalik commented Mar 12, 2026

Copy link
Copy Markdown
Member

Closes #60

Summary

Adds a Launch at Login feature using the modern SMAppService API (macOS 13+). The toggle appears in two places:

  1. Setup Wizard → "You're All Set!" step — natural place to enable it during first-time setup
  2. Settings → General → Behavior — for changing the preference later

Both toggles stay in sync via the same setLaunchAtLogin() method. No helper app or additional entitlements required.

Implementation

AppState (AppState.swift)

  • setLaunchAtLogin(_ enabled: Bool) — Registers/unregisters via SMAppService.mainApp. On failure, reverts the launchAtLogin preference to match the actual system state so the toggle never gets out of sync.
  • syncLaunchAtLogin() — Called once on init to reconcile the persisted @AppStorage preference with the system's login item state. Handles edge cases like re-installs, or the user toggling the setting directly in System Settings → General → Login Items.
  • Added import ServiceManagement

SettingsView (SettingsView.swift)

  • Added a Toggle("Launch at Login", ...) as the first item in the Behavior section
  • Uses a custom Binding that routes through setLaunchAtLogin()

OnboardingView (OnboardingView.swift)

  • Added a Launch at Login toggle on the Setup Wizard's completion step ("You're All Set!")
  • Styled with a sunrise icon, description text, and blue-tinted background card
  • Uses the same custom Binding through setLaunchAtLogin(), staying in sync with the Settings toggle

No entitlement changes needed

SMAppService.mainApp works with both ad-hoc signed and Developer ID signed apps without any additional entitlements.

Tests Added

5 new tests in LaunchAtLoginTests:

  • testLaunchAtLoginDefaultsToFalse — verifies the default preference
  • testLaunchAtLoginPersistence — verifies @AppStorage round-trip
  • testSetLaunchAtLoginEnableUpdatesPreference — verifies enable syncs with system state
  • testSetLaunchAtLoginDisableUpdatesPreference — verifies disable syncs with system state
  • testSetLaunchAtLoginToggleRoundTrip — verifies enable → disable doesn't crash and stays consistent

Testing

All 62 tests pass (swift test). Manually verified:

  • Toggle appears on Setup Wizard completion step
  • Toggle appears in Settings → General → Behavior
  • Both toggles stay in sync
  • App correctly registers/unregisters as a login item

Add a 'Launch at Login' toggle in Settings → General → Behavior that
registers VocaMac as a login item using the modern SMAppService API
(macOS 13+). No helper app or additional entitlements required.

Implementation:
- Wire up the existing launchAtLogin @AppStorage property to
  SMAppService.mainApp.register()/unregister()
- Add setLaunchAtLogin() method with error handling that reverts the
  preference to match actual system state on failure
- Add syncLaunchAtLogin() on init to reconcile persisted preference
  with system state (handles re-installs, manual System Settings changes)
- Add Toggle in SettingsView General tab Behavior section
- Use custom Binding to route through setLaunchAtLogin() instead of
  directly binding to @AppStorage

Closes #60
Add a Launch at Login switch in the menu bar popover's actions section,
above the Settings button. Uses the same Binding through setLaunchAtLogin()
as the Settings toggle, ensuring both stay in sync.
Remove the Launch at Login toggle from the menu bar popover (it didn't
fit well visually) and add it to the Setup Wizard's completion step.
The toggle now appears on the 'You're All Set!' screen with a sunrise
icon and description text, giving users a natural place to enable it
during initial setup. It remains in sync with the Settings toggle.
@jatinkrmalik
jatinkrmalik merged commit 06c08c7 into main Mar 12, 2026
1 check passed
@jatinkrmalik
jatinkrmalik deleted the feat/launch-at-login branch August 22, 2026 05:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Auto-start VocaMac on login

1 participant