Skip to content

refactor(services): inject AppServices into SyncCoordinator and add five missing singletons#1155

Merged
datlechin merged 1 commit into
mainfrom
refactor/inject-services-into-sync-coordinator
May 9, 2026
Merged

refactor(services): inject AppServices into SyncCoordinator and add five missing singletons#1155
datlechin merged 1 commit into
mainfrom
refactor/inject-services-into-sync-coordinator

Conversation

@datlechin

Copy link
Copy Markdown
Member

Summary

Largest single tranche so far of the AppServices DI completion. SyncCoordinator now holds an injected services: AppServices and reads every dependency through it instead of dialing .shared directly.

AppServices gains five fields: tagStorage, sshProfileStorage, licenseManager, conflictResolver, syncMetadataStorage. The live initializer threads .shared defaults through.

SyncCoordinator:

  • private init() becomes init(services: AppServices = .live).
  • The instance fields changeTracker, metadataStorage, conflictResolver are now sourced from services.syncTracker / services.syncMetadataStorage / services.conflictResolver rather than from raw .shared. The instance-field shape is preserved so the 50+ in-method references (changeTracker.markDirty, metadataStorage.lastSyncDate, etc.) compile unchanged.
  • 34 raw .shared reads in method bodies converted via mechanical sed: ConnectionStorage.shared -> services.connectionStorage, GroupStorage.shared -> services.groupStorage, TagStorage.shared -> services.tagStorage, SSHProfileStorage.shared -> services.sshProfileStorage, LicenseManager.shared -> services.licenseManager, AppSettingsStorage.shared -> services.appSettingsStorage, AppSettingsManager.shared -> services.appSettings, AppEvents.shared -> services.appEvents.
  • The class-level static let shared = SyncCoordinator() line stays unchanged (still uses the default .live init), so no AppDelegate or call-site change is needed.

Why this matters

This is the next slice of audit findings 3.1 + arch 5.1. SyncCoordinator was the second-largest concentration of raw .shared reads after the storage trio (D3). After this PR, every singleton it touches flows through the AppServices container.

Test plan

  • Enable iCloud sync in settings; confirm initial full sync runs and connections / groups / tags / profiles upload.
  • Make a local edit (rename a connection); confirm it pushes on the next sync.
  • Receive a remote change from another device; confirm it applies locally.
  • Disable then re-enable sync; confirm the dirty-marking pass runs without crashing.
  • swiftlint --strict clean.

@datlechin datlechin merged commit b9bbc17 into main May 9, 2026
2 checks passed
@datlechin datlechin deleted the refactor/inject-services-into-sync-coordinator branch May 10, 2026 10:36
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.

1 participant