Release 1.7.0

- Event-driven background sync, replacing the hourly launchd StartInterval
  poll (only fired if the Mac happened to be awake at that instant, and got
  throttled/coalesced by macOS). Once saved routes exist: registers as a
  login item (SMAppService.mainApp), removes any old launchd schedule, and
  reacts to EKEventStoreChanged (debounced ~3s), NSWorkspace.didWakeNotification,
  plus a 30-min fallback timer as a safety net. Auto-sync always writes,
  matching what the old scheduled runs did.
- This lives in BusyMirrorAppController (app-lifetime), not ContentView —
  ContentView's own EKEventStoreChanged observer is torn down when the main
  window closes, which would make auto-sync a no-op exactly when it needs to
  keep working (window closed, menu-bar-only). Confirmed via MenuBarSupport's
  existing "Sync Now" handler, which already has to reopen the window before
  it can run anything.

All 47 unit tests pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-26 18:37:23 +02:00
co-authored by Claude Sonnet 5
parent 61cea918a6
commit 08e9fe5325
5 changed files with 201 additions and 14 deletions
+4 -4
View File
@@ -410,7 +410,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 22;
CURRENT_PROJECT_VERSION = 23;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = BusyMirror/Info.plist;
@@ -421,7 +421,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.6.1;
MARKETING_VERSION = 1.7.0;
PRODUCT_BUNDLE_IDENTIFIER = com.cqrenet.BusyMirror;
PRODUCT_NAME = "$(TARGET_NAME)";
REGISTER_APP_GROUPS = YES;
@@ -440,7 +440,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 22;
CURRENT_PROJECT_VERSION = 23;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = BusyMirror/Info.plist;
@@ -451,7 +451,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.6.1;
MARKETING_VERSION = 1.7.0;
PRODUCT_BUNDLE_IDENTIFIER = com.cqrenet.BusyMirror;
PRODUCT_NAME = "$(TARGET_NAME)";
REGISTER_APP_GROUPS = YES;