Skip to content

macOS: add native FileProvider on-demand sync - #1128

Draft
restot wants to merge 4 commits into
opencloud-eu:mainfrom
restot:upstream/macos-fileprovider
Draft

restot wants to merge 4 commits into
opencloud-eu:mainfrom
restot:upstream/macos-fileprovider

Conversation

@restot

@restot restot commented Sep 27, 2026

Copy link
Copy Markdown

macOS users currently have to choose whole folders for local synchronization. This adds native FileProvider locations in Finder so files can be listed without downloading their contents and downloaded when opened.

When a compatible FileProvider extension is bundled, the client defaults to on-demand mode. General Settings offers traditional folder sync after restart. The modes are mutually exclusive, and switching preserves existing local files and saved folder configuration.

This draft is for upstream architecture and integration review while independent testing continues. It condenses the implementation developed in restot/opencloud-desktop#3 into four commits against current upstream main:

  1. Native FileProvider implementation and Finder socket extensions.
  2. Desktop account lifecycle, credential exchange, status, exclusive sync modes, and build integration.
  3. Regression tests, a disposable signed Finder fixture, and concise behavior/test documentation.
  4. Isolate the existing macOS startup-setting test from installed clients and other build paths.

Local agent files, implementation diaries, old demo code, fork release history, and fork packaging/crash-report tooling are excluded. Tests and the documentation needed to review and exercise the feature remain.

Behavior and architecture

The host registers a domain per account space and supplies credentials through signed XPC. The extension stores domain credentials in Keychain, performs DAV operations, and maintains item identities, change history, and local Finder metadata in SQLite. Provider status feeds the tray and account Settings. Traditional Finder overlays use a Unix socket in the shared App Group container.

The provider supports hydration and eviction, native download/pinning policies, file operations with conditional writes, server Trash/restore/permanent deletion, scoped cloud search, remote thumbnails, and browser sharing/version actions. Supported operations depend on server capabilities and permissions. Finder metadata stays local to the Mac; virtual Shares locations do not advertise space-specific Trash or search. The implementation does not reproduce iCloud's private sidebar popover or add Desktop and Documents backup.

The FileProvider extension currently requires macOS 26 and Xcode 26/macOS 26 SDK to build. FinderSync retains its upstream macOS 10.15 deployment target. The host checks provider availability and uses traditional sync on unsupported systems. Personal signing-team defaults were removed; a signed installation requires matching host/extension identities and App Group entitlements.

See behavior and build requirements and test instructions.

Validation

On this branch, using an Apple Silicon Mac, macOS 26, Xcode 26, and Qt 6.9.2:

  • Desktop client and test targets build successfully.
  • Both extensions build for arm64 and x86_64 without signing.
  • The full selected CTest run passed 42 of 43 suites. The existing startup-setting test failed because it accessed the real organization-domain LaunchAgent rather than its random test name. Commit 4 isolates that test, and the complete testutility suite passes on rerun. The interactive credential-manager test is excluded; signed Keychain behavior is checked separately.
  • The signed Finder fixture passes XPC caller authorization, Keychain isolation/recovery, enumeration/hydration, upload/rename/delete, package contents, native Trash/restore/permanent deletion, status/pending work, offline reads, eviction/relaunch, revocation, disconnect/reconnect, and cleanup.
  • Shell/Python syntax and git diff --check pass.

The fixture uses a local DAV server and isolated accounts. Clean-machine installation, other operating systems, production-server combinations, and the upstream release-signing pipeline still need validation. The original development build's General Settings switches were manually tested in both directions; those UI checks have not been repeated on this cleaned branch. The fork's published v0.4 is a separate artifact, not a build of this commit series.

Remaining work and review questions

  • Settings indicator still checks FinderSync rather than the active provider and needs a state refresh.
  • Cross-device folder report needs confirmation of the exact iOS-created and Finder-created empty-folder workflows on the current implementation.
  • A failed new upload discarded before receiving a server ID can leave its error visible until recovery/status reset. Unrelated enumeration cannot safely prove success.
  • I would appreciate guidance on fitting this architecture into the existing VFS abstraction, the default/migration behavior, minimum macOS support, signing/packaging, and whether maintainers would prefer smaller follow-up PRs.

Please use a test account and disposable files for trials. Swift/C++ review and reproducible reports with sanitized logs would help prepare this for merging.

Cc @dragotin @TheOneRing. Thanks to @3zero2 for early testing and detailed reports, and @bilogic for suggesting this focused upstream series.

Related: opencloud-eu/Roadmap#52 and #166. These feature requests remain open while this draft is under review.

restot added 4 commits September 27, 2026 11:10
Add per-space on-demand enumeration, transfers, persistent metadata, signed credential exchange, and Finder actions using the public FileProvider APIs. Move FinderSync transport to the shared app-group socket and retain its existing deployment target.
Connect FileProvider domains to account credentials and lifecycle, expose provider progress and errors, and select on-demand or traditional sync exclusively at startup. Bundle both extensions with matching versions and preserve inactive folder configuration.
Add Qt lifecycle and provider-selection coverage, Swift regression suites, and a signed disposable Finder fixture backed by a local DAV server. Document supported Finder behavior, macOS requirements, and reproducible test commands.
Use a temporary organization domain for the startup test because macOS ignores the application-name argument when choosing its LaunchAgent plist. Remove only the test-owned entry and restore the domain even when an assertion fails.
@nicokaiser

Copy link
Copy Markdown

@restot Your fork is already much better than anything OpenCloud (no FileProvider at all) and Nextcloud (broken FileProvider) offers! Thanks for the effort, hope this will somehow make it into upstream.

(There are still bugs, especially when connecting from a slow or unstable connection – but the official clients also have severe issues with this, so maybe it's not the fork's fault)

@restot

restot commented Sep 29, 2026

Copy link
Copy Markdown
Author

@restot Your fork is already much better than anything OpenCloud (no FileProvider at all) and Nextcloud (broken FileProvider) offers! Thanks for the effort, hope this will somehow make it into upstream.

(There are still bugs, especially when connecting from a slow or unstable connection – but the official clients also have severe issues with this, so maybe it's not the fork's fault)

@nicokaiser tysm!
If you're would be so kind to open issues in my fork repo and report them. Im committed to deliver excellent quality software so it would be impossible to not include. Even if its legacy bugs I can fix them no problem.

@bilogic

bilogic commented Oct 14, 2026 •

Copy link
Copy Markdown

@restot

This PR is still in draft, but already at 101 files, are you planning to bring that number down?

From my experience, if the change is so big, you probably want to gate it as a feature flag, i.e. accepting your PR will lead to no change in the app, unless this feature is enabled by the user.

And I would start with getting the UI merged first, 0 functionality at all. Otherwise I don't see how the maintainers will accept this.

They have been quiet on the other issue, it doesn't look promising.

This branch has not been deployed

No deployments
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.

3 participants