Skip to content

humanjesse/SwipeLabel

SwipeLabel - Tinder for ML Data Labeling

Build License Android Kotlin

An Android app that makes data annotation fun and efficient! Swipe through your JSON entries, label them with custom fields, and export your work to CSV.

Try SwipeLabel

Want to try the app without building from source?


Features

  • πŸ“± Tinder-style interface: Swipe gestures or tap buttons to dislike/like - cards fill the screen for maximum visibility
  • πŸ‘† Multi-card views: Configure multiple card views per entry, tap left/right to navigate between them
  • ⬅️ Undo functionality: Go back to previous cards with confirmation dialog (deletes annotation on undo)
  • ⚠️ Data protection: Warning dialog prevents accidental data loss when starting new projects
  • 🎯 Unlimited custom fields: Add as many annotation fields as you need
  • πŸ”˜ 4 Field Types: TEXT, NUMBER, CHECKBOX (multi-select), SLIDER (numeric range)
  • πŸ“Š Multiple JSON formats: Auto-detects JSON Array, JSONL, and Label Studio formats
  • πŸ” Format compliance: UTF-8 BOM support, key-order independence, spec-compliant parsing
  • πŸ”— Nested field support: Dot-notation paths for accessing nested JSON (e.g., data.image)
  • πŸ“– 3 Display Modes: Reading (scrollable text), Scaled (ASCII art optimized), Image (URL/base64)
  • πŸ–ΌοΈ Image Support: Display images from URLs or base64 data with smart caching (Coil) and pinch-to-zoom
  • 🎨 ASCII Art Support: Monospace font, auto-sizing, and proper alignment for ASCII art
  • πŸ“ˆ Statistics Dashboard: View like/dislike ratio, dataset progress, and field completion rates
  • πŸ’Ύ CSV & Label Studio export: Export to CSV or back to Label Studio JSON format
  • βš™οΈ Settings Screen: Manage privacy and appearance preferences
  • πŸ”’ Privacy Controls: GDPR-compliant crash reporting opt-out
  • 🌈 Theme Selection: Light/Dark/System modes with lavender & sage color palette
  • 🎨 Material Design 3: Beautiful, modern UI with custom brand icon
  • 🏷️ Custom App Icon: Adaptive icon featuring lavender card and swipe gesture on sage green
  • πŸ—οΈ MVVM Architecture: Clean, maintainable code structure
  • πŸ› Crash Reporting: Production-ready error tracking with Firebase Crashlytics

How to Use

  1. Select JSON File: Choose a JSON file containing your data
  2. Configure Fields:
    • Select identifier field (unique ID for each entry)
    • Add card views: select field + display mode (Reading/Scaled/Image) for each
    • Add unlimited custom annotation fields with 4 types:
      • TEXT: Free-form text input
      • NUMBER: Numeric input with validation
      • CHECKBOX: Multi-select from custom options (min 2)
      • SLIDER: Numeric slider with custom min/max/step
  3. Start Swiping:
    • Tap left/right sides of card to navigate between card views
    • Swipe left or tap Dislike button to dislike an entry
    • Swipe right or tap Like button to label it
  4. Fill Annotations: Enter data for your custom fields (tap Done on keyboard to dismiss)
  5. View Statistics: Check like/dislike ratio, dataset progress, and field completion
  6. Export Results: Choose export format and save to Downloads folder
    • CSV: For spreadsheets and data analysis
    • Label Studio JSON: Re-import to Label Studio (only for Label Studio source files)
  7. Manage Settings: Tap "Settings" on home screen to:
    • Control crash reporting (on/off)
    • Choose theme (Light/Dark/System)
    • Test crash reporting: Tap "System default" 7 times to unlock Developer Tools (debug builds only)

Sample Data

Multiple test files included for different JSON formats:

JSON Array Format (Original)

  • examples/sample_data.json - 10 simple text entries
  • examples/asciieverything_batch_000_100pieces_20250928_141020.json - 100 ASCII art entries

JSONL Format (Newline-delimited)

  • examples/test_jsonl.jsonl - Standard JSONL format
  • examples/test_jsonl_with_bom.jsonl - Tests UTF-8 BOM handling

Label Studio Format

  • examples/test_labelstudio.json - Standard Label Studio tasks
  • examples/test_labelstudio_unordered.json - Tests key-order independence

All formats auto-detected - just select the file!

Example configuration (any format):

  • Identifier Field: id
  • Display Field: text or art (arrays render line-by-line)
  • Custom Fields: Define based on your labeling needs

Tech Stack

  • Language: Kotlin 2.2.0
  • UI: Jetpack Compose with Material Design 3
  • Architecture: MVVM + Clean Architecture
  • Dependency Injection: Hilt 2.57.2
  • Database: Room 2.8.1 (v6 with entry status tracking and normalized annotation_values table)
  • Background Processing: WorkManager with Hilt integration
  • JSON Parsing: Kotlinx Serialization with streaming API (memory-efficient for large files)
  • State Management: DataStore for session persistence and app preferences
  • Image Loading: Coil 3.3.0 with smart caching (25% memory + 250MB disk) and network support (OkHttp)
  • Crash Reporting: Firebase Crashlytics with custom instrumentation
  • Analytics: Firebase Analytics
  • CSV Export: OpenCSV
  • Navigation: Navigation Compose
  • Build: Gradle 8.9, AGP 8.7.3

Technical Notes

Android File Access & JSON Format Support

This app handles JSON file access using a streaming + background import approach with automatic format detection:

  1. File Selection: Uses ActivityResultContracts.OpenDocument() to let users select JSON files
  2. Format Detection: JsonFormatDetector auto-detects JSON Array, JSONL, or Label Studio format
  3. UTF-8 BOM Handling: Automatically strips BOM if present (common in Windows files)
  4. Immediate Copy: Selected file copied to app storage with temporary URI permission
  5. Background Import: WorkManager processes large files in background with progress tracking
  6. Streaming Parser: JsonStreamingParser uses kotlinx.serialization streaming API
    • Processes entries one-by-one (memory-efficient)
    • Batch inserts every 100 entries to Room database
    • Tested with 100-entry ASCII art dataset
  7. Session Persistence: DataStore maintains config and progress across app restarts

Supported JSON Formats:

  • JSON Array: [{...}, {...}] - Standard array format
  • JSONL: {...}\n{...}\n - Newline-delimited (one object per line)
  • Label Studio: [{"data": {...}}] - Nested data key format with dot-notation support (e.g., id, data.image)

Why this approach?

  • Android's DownloadProvider doesn't support persistent URI permissions
  • Large JSON files (100+ MB) won't crash the app
  • Users can close app during import - WorkManager continues in background
  • Format auto-detection provides seamless user experience

Key Implementation Files:

  • HomeScreen.kt / FileManager.kt - Copies file to app storage
  • JsonFormatDetector.kt - Auto-detects JSON format with BOM support
  • ImportWorker.kt - Background processing with WorkManager
  • JsonStreamingParser.kt - Memory-efficient streaming with batch insertion
  • SessionManager.kt - DataStore persistence for config and progress
  • docs/format-specifications/ - Complete format specs and compliance docs

Project Structure

com.example.swipelabel/
β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ local/          # Room database and DAOs (Entry, Project, Annotation)
β”‚   β”œβ”€β”€ model/          # Data models
β”‚   β”œβ”€β”€ repository/     # DataRepository, JsonStreamingParser, FileManager
β”‚   └── workers/        # WorkManager background tasks
β”œβ”€β”€ domain/
β”‚   └── usecase/        # Business logic use cases
β”œβ”€β”€ ui/
β”‚   β”œβ”€β”€ components/     # Shared composables (display modes)
β”‚   β”œβ”€β”€ navigation/     # Navigation graph
β”‚   β”œβ”€β”€ screens/        # UI screens (Home, ProjectList, Settings, Config, Swipe, Statistics, Export)
β”‚   └── theme/          # App theming
β”œβ”€β”€ util/               # Utilities (CrashlyticsLogger)
└── di/                 # Dependency injection modules

Building the App

Prerequisites

  • Android Studio Hedgehog (2023.1.1) or newer
  • JDK 17
  • Android SDK with API 34
  • Firebase project (for crash reporting)

Firebase Setup (Required)

To build this app, create your own Firebase project and add google-services.json - see FIREBASE_SETUP.md

Quick steps:

  1. Create a Firebase project at https://console.firebase.google.com/
  2. Register your Android app with package name: com.example.swipelabel
  3. Download google-services.json and place it in the app/ directory
  4. See FIREBASE_SETUP.md for detailed instructions

Note: The google-services.json file is gitignored. A template (google-services.json.example) is provided for reference.

Steps

  1. Clone the repository
  2. Set up Firebase (see above)
  3. Open project in Android Studio
  4. Sync Gradle files
  5. Run on emulator or physical device (API 26+)

First Build

./gradlew build

Install on Device

./gradlew installDebug

Testing the App

  1. Copy examples/sample_data.json to your Android device
  2. Open SwipeLabel app
  3. Tap "Select JSON File" and choose the sample data
  4. Configure as suggested above
  5. Start swiping and labeling!
  6. Export your annotations to CSV

Releases

See what's new: Check out the Releases page for detailed release notes and version history.

Download the app: To get the latest beta version, sign up at swipelabel.com

Future Enhancements

Potential features for future versions:

  • Support for more field types βœ… Implemented in v1.3.0
  • Multiple display fields on cards βœ… Implemented in v1.5.0
  • Undo swipe functionality βœ… Implemented in v1.0.8
  • Image display support βœ… Implemented in v1.6.0
  • Nested field support βœ… Implemented in v1.6.1
  • Statistics dashboard βœ… Implemented in v1.7.0
  • Crash reporting βœ… Implemented in v1.8.0
  • Privacy controls βœ… Implemented in v1.8.0
  • Performance monitoring (Firebase Performance)
  • Remote configuration
  • Search and filter entries
  • Batch operations
  • Cloud sync

License

SwipeLabel is licensed under the Apache License, Version 2.0. See LICENSE for the full license text.

Copyright 2025 SwipeLabel Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Third-Party Licenses

This project uses several open source libraries. See NOTICE for full attribution and license information for all dependencies.

Credits

Built with ❀️ using modern Android development practices and Claude AI assistance.

About

ML data labeling app with intuitive ui!

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

No packages published

Languages