Skip to content

edward-hsu-1994/FileSync

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

26 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

FileSync Logo

FileSync

macOS Swift SwiftUI License

FileSync is a lightweight, high-performance, and native macOS menu bar file synchronization tool. Designed with SwiftUI and powered by SwiftData, it offers an elegant, distraction-free interface to manage and orchestrate automated folder-to-folder replication tasks efficiently under the strict constraints of the macOS App Sandbox.

By leveraging Security-Scoped Bookmarks, FileSync persists permission scopes across system restarts and USB mounts, ensuring reliable backup pipelines without user intervention.


✨ Key Features

  • Menu Bar Resident (Status Bar App): Resides unobtrusively in your macOS status bar, accessible in one click without cluttering your Dock.
  • Strict Sandbox Compatibility: Fully compliant with Mac App Sandbox requirements. Persists folder permissions across launches recursively using security-scoped bookmarks.
  • Comprehensive Sync Triggers:
    • Manual Trigger: Run synchronization tasks on-demand.
    • USB Device Trigger: Detects external disk mounting/unmounting events instantly and executes designated tasks automatically.
    • Real-Time Monitoring: Watches directories via macOS FSEvents and triggers instant synchronization when files are updated, created, or deleted.
    • Scheduled Interval: Triggers runs on a recurring cron-like schedule (e.g., every few minutes/hours).
  • Metadata Protection & Exclusions: Avoids backup pollution by excluding platform metadata like AppleDouble files (._*) during deletion passes.
  • Dynamic Localization: Instantly switch languages (Traditional Chinese, English, Simplified Chinese, Japanese) directly inside preferences without restarting the application.
  • Fluent UI & Interactive States: Fine-tuned components with smooth transition animations, dedicated history timelines, clipboard copies, and tooltip helpers.

πŸ—οΈ Architecture

FileSync coordinates user interface components, persistence database layers, and daemon triggers asynchronously:

graph TD
    App[FileSyncApp.swift] --> |Initialize SwiftData| Data[SyncTaskDataModel]
    App --> |Register Menu Item| Bar[StatusBarManager.swift]
    Bar --> |Displays View| Main[ContentView.swift]
    Main --> |File Dialogs / Create Bookmarks| Form[TaskFormView.swift]
    Main --> |User Language Config| Prefs[PreferencesView.swift]
    Main --> |Translate Keys| Lang[LanguageManager]
    Main --> |Schedule / FSEvents| BackgroundSync[BackgroundSyncManager.swift]
    BackgroundSync --> |Executes Rsync| ShellTask[SyncTask.swift]
Loading

Module Descriptions

  • FileSyncApp.swift: Bootstraps the application, configures the SwiftData storage container, and initializes the menu bar status manager.
  • StatusBarManager.swift: Handles the system status bar icon, controls popover behaviors, and manages window focus events.
  • BackgroundSyncManager.swift: The orchestrator of background execution. It runs file watchers (FSEventStream) for real-time mode and configures timer scheduling.
  • SyncTask.swift: Represents the domain business logic and rsync subprocess execution wrapper. Inspects paths validity before running, resolves sandbox URLs via security-scoped bookmarks, and streams progress updates.
  • TaskFormView.swift: Interactive modal for creating and updating tasks. Calls standard macOS NSOpenPanel to secure directory read-write scopes.

πŸ› οΈ Build and Installation

System Requirements

  • Operating System: macOS 15.0 or later.
  • Development Tooling: Xcode 16.0 or later.

Makefile Automation

A Makefile is provided to simplify development workflows. You can execute:

  • make (or make all): Compiles the application, terminates any running instance, and relaunches the fresh build.
  • make build: Compiles the project using xcodebuild.
  • make run: Dynamically locates and launches the compiled FileSync.app from DerivedData.
  • make restart: Force-stops any active FileSync process and relaunches the application.
  • make clean: Cleans up Xcode build artifacts.

Manual Compilation

Alternatively, you can build manually using the commands below:

# 1. Kill any existing FileSync instances to avoid database locking
killall FileSync 2>/dev/null || true

# 2. Build the Debug scheme targeting macOS
DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer xcodebuild -scheme FileSync -configuration Debug build

# 3. Launch the compiled application
open ~/Library/Developer/Xcode/DerivedData/FileSync-*/Build/Products/Debug/FileSync.app

πŸ”’ Security & Sandbox Entitlements

To pass App Store verification and run securely under Sandbox constraints, the application claims the following entitlements inside FileSync.entitlements:

<!-- FileSync.entitlements snippet -->
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.files.volumes.removable-client-default</key>
<true/>
<key>com.apple.security.files.volumes.network-client-default</key>
<true/>

🌐 Localization Guide

FileSync supports dynamic localization, allowing users to switch languages instantly from the Preferences view without restarting the application. The system currently supports English, Traditional Chinese, Simplified Chinese, and Japanese.

Localization is managed centrally by LanguageManager and static properties exposed in the L10n helper struct within LocalizableStrings.swift.

1. How to Modify Existing Translations

To update or correct translations for any of the supported languages, locate the respective Localizable.strings file:

Open the file and modify the translation value for the desired key. For example:

"sync_tasks" = "Your New Translation";

2. How to Add a New Translation Key

To introduce a new localized string across the app:

  1. Add Key-Value Pairs to all existing Localizable.strings files:
    "my_new_string_key" = "Localized text";
    
  2. Expose the Property in LocalizableStrings.swift under the L10n struct:
    static var myNewString: String { localized("my_new_string_key") }
  3. Use it in SwiftUI Views:
    Text(L10n.myNewString)

3. How to Add Support for a New Language

To add support for a completely new language (e.g., French - fr):

  1. Add Localization in Xcode:
    • Open the project in Xcode.
    • Select the project in the Project Navigator, go to the Info tab, and find the Localizations section.
    • Click the + button and select the new language (e.g., French). Ensure Localizable.strings is checked for translation generation.
  2. Translate the Strings:
    • Edit the newly created Localizable.strings file under fr.lproj/ and translate all the keys.
  3. Declare the Language Display Name:
    • Add the language name translation key to all Localizable.strings files (e.g., "french" = "French (FranΓ§ais)";).
    • Add a static helper property to L10n in LocalizableStrings.swift:
      static var french: String { localized("french") }
  4. Register in the Preferences View:
    • Open PreferencesView.swift.
    • Inside the Picker("", selection: $languageManager.selectedLanguage) block, add a new tag matching the ISO 639-1 language code:
      Text(L10n.french).tag("fr")

πŸ“ Commit Message Guidelines

To maintain consistency and readability across the project history, please follow these guidelines when writing commit messages.

Message Structure

A commit message consists of a Header, a Body, and a Footer separated by blank lines:

<type>(<scope>): <subject>

<body>

<footer>

1. Header: <type>(<scope>): <subject>

  • type (Required): The category of the change. Must be one of the following:
    • feat: A new feature or change in functionality.
    • fix: A bug fix.
    • docs: Documentation only changes.
    • style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc.).
    • refactor: A code change that neither fixes a bug nor adds a feature.
    • perf: A code change that improves performance.
    • test: Adding missing tests or correcting existing tests.
    • chore: Maintain. Changes to the build process, auxiliary tools, or configuration files (no source code change).
    • revert: Reverts a previous commit.
  • scope (Optional): The area affected by the change (e.g., database, ui, triggers).
  • subject (Required): A succinct description of the change:
    • Limit to 50 characters or less.
    • Do not capitalize the first letter.
    • Do not end with a period.

2. Body (Optional)

  • Detailed explanation of the change (What, Why, and How).
  • Wrap lines at 72 characters.

3. Footer (Optional)

  • Reference issue tracking numbers (e.g., fixes #1246).
  • Record breaking changes using BREAKING CHANGE: prefix.

Examples

  • feat: add email notification feature
  • feat(coupon): add search button and adjust layout
  • fix: resolve pie chart legend overflow
  • style: unify line endings CRLF to LF
  • docs: update README configuration section
  • chore: adjust unit testing environment
  • refactor(notification): simplify email sender logic

🀝 Contributing

Contributions make the open-source community an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

πŸ“„ License

Distributed under the MIT License. See LICENSE for more information.


πŸ‘€ Author

About

Local file synchronization tool for macOS via rsync. Supports directory monitoring, USB insertion triggers, scheduled syncs, and 100% privacy.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors