A native macOS app that syncs Moodle and Open LMS course content directly to your Mac using Apple's File Provider framework.
Your course files right in Finder, behaving exactly like iCloud Drive or Dropbox.
Findle is built to make managing university or school materials painless. Instead of constantly logging into Moodle to download PDFs and slides, Findle seamlessly integrates your courses right into macOS Finder. It's built from the ground up in Swift and SwiftUI, leveraging Apple's native File Provider framework to ensure your files are synced securely, dynamically, and entirely on-demand.
demo.mp4
Browse your courses, toggle sync preferences, and monitor progress directly from the native macOS interface.
| Direct Finder integration | Quick Actions without Leaving Finder |
|---|---|
![]() |
![]() |
| Findle seamlessly integrating with Finder's sidebar, behaving exactly like iCloud Drive or Dropbox. | Perform quick actions directly from the Finder app, no need to open any browser. |
![]() |
![]() |
| Connect to your Moodle server and authenticate securely. | Simple and beautiful onboarding steps thanks to alexmodrono/Airlock. |
- Native macOS Experience: Built specifically for the Mac using Swift and SwiftUI, so it feels fast and right at home.
- File Provider Integration: First-class Finder sidebar presence. Files only download when you actually need them, saving local disk space.
- Secure by Default: Authentication happens via the official Moodle Web Services API, and credentials are stored securely in the macOS Keychain.
- Smart Sync: The app handles automatic course discovery, enumerates content, and performs incremental syncs using per-course change tracking.
- Automatic Updates: Built-in update checking via Sparkle, so you always have the latest version.
- Efficient Storage: Under the hood, a local SQLite database caches metadata so you can browse your course structure instantly, using placeholder files until you double-click them.
Download the latest .dmg from the Releases page. Open the disk image and drag Findle to your Applications folder.
brew tap alexmodrono/tap
brew install --cask findle- macOS 14.0 (Sonoma) or later
- Xcode 16.0 or later
- Swift 6.0
- XcodeGen (for generating the Xcode project)
-
Install XcodeGen (if you haven't already):
brew install xcodegen
-
Generate the Xcode project:
xcodegen generate
-
Open the project:
open Foodle.xcodeproj
-
Configure Code Signing: The File Provider extension requires code signing with a valid Apple Development Team. Go into the Xcode project settings and select your own Development Team for all targets before building.
-
Select the
Foodlescheme, build, and run.
Note: The Xcode project and scheme are named
Foodlefor historical reasons, but the built app is called Findle.
Before shipping, use the Release-like Foodle-Staging scheme. It keeps optimization and hardened runtime behavior close to Release while still allowing tests to run.
xcodegen generate
./scripts/staging-smoke-test.shThat script builds an unsigned optimized app in Staging and runs the test suite against it. It is the fast validation pass for optimized code paths, but it is not suitable for File Provider registration or end-to-end SSO/Finder checks because the extension is not code signed in that flow.
For real pre-ship runtime validation, build a signed Staging app:
xcodegen generate
./scripts/staging-signed-build.shIf your project does not already have a team selected in Xcode, provide one from the shell:
DEVELOPMENT_TEAM=ABCDE12345 ./scripts/staging-signed-build.shUse the signed Staging app for the manual checklist: SSO completion, Finder integration, restart/session restore, sync, and file materialization.
Findle is split into a modular set of frameworks and targets. This keeps the separation of concerns clean and makes it easier to work on isolated features.
| Module | Purpose |
|---|---|
SharedDomain |
Core types, models, state machines, and shared error handling. |
FoodleNetworking |
The Moodle API client, authentication logic, and Keychain integration. |
FoodlePersistence |
The SQLite database layer, metadata cache, and sync cursors. |
FoodleSyncEngine |
Orchestrates the sync process, computes diffs, and manages downloads. |
FoodleFileProvider |
The Apple File Provider extension that hooks directly into Finder. |
Findle (App) |
The main SwiftUI app shell, handling onboarding, diagnostics, and settings. |
graph LR
M[Moodle Server] --> N[Networking]
N --> S[SyncEngine]
S --> P[Persistence]
P --> F[FileProvider]
F --> M_F[macOS Finder]
Reliability is maintained with unit and integration tests. You can run the test suites directly in Xcode using Cmd+U, or via the command line:
xcodebuild test -project Foodle.xcodeproj -scheme SharedDomainTests
xcodebuild test -project Foodle.xcodeproj -scheme PersistenceTestsMock API responses and test fixtures can be found in the Fixtures/ directory.
Findle/
├── Sources/
│ ├── App/ # Main macOS application
│ ├── SharedDomain/ # Shared models and types
│ ├── Networking/ # Moodle API client
│ ├── Persistence/ # SQLite database
│ ├── SyncEngine/ # Sync orchestration
│ └── FileProviderExtension/ # Apple File Provider extension
├── Tests/ # Unit and integration tests
├── Fixtures/ # Mock API response data
├── Resources/ # Plists, entitlements, and XCAssets
└── project.yml # XcodeGen project definition
There's still a lot to be done. Here is what is currently on the radar:
- Complete the end-to-end vertical slice (authenticate -> enumerate -> Finder placeholders)
- Background sync refresh
- Offline pinning support
- Multi-account support
- Optional offline mirror to a user-chosen folder
- Spotlight integration
- Assignment submission support directly from the Mac
- Support for additional LMS backends
Contributions are always welcome! If you have an idea to improve Findle or fix a bug:
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request for review.
This project is licensed under the Apache License 2.0. See the LICENSE file for the full details.



