Skip to content

Repository files navigation

Phototagger

Phototagger is a SwiftUI iPhone app for people whose photo library has outgrown Apple Photos. It adds custom tagging, fast retrieval, and cleanup workflows on top of PhotoKit by maintaining a local metadata index in SQLite via GRDB.

It is intentionally opinionated about modern iOS development: Swift 6.2, SwiftUI, @Observable, async/await, PhotoKit, and a database-backed architecture that keeps the UI responsive even with large libraries.

Feature Highlights

  • Inbox-first triage flow for untagged photos
  • Custom tags stored locally and mapped to PHAsset.localIdentifier
  • Browse/search experience powered by indexed metadata
  • Duplicate detection using Vision feature prints and DCT-based perceptual hashing
  • Cleanup workflows for screenshots and large videos
  • Capture flow that lets users shoot and tag in one motion
  • Privacy-forward architecture with local-first storage

Architecture

The app is organized around a clear split between product surfaces and infrastructure:

Phototagger/
├── Models/       GRDB-backed records and lightweight domain types
├── Database/     SQLite schema, migrations, and high-performance queries
├── Services/     App state, indexing, PhotoKit integration, diagnostics
└── Views/        Feature-driven SwiftUI screens and reusable components

Core pieces:

  • AppState is the @Observable main-actor coordinator for shared app state.
  • PhotoLibraryService wraps PhotoKit and authorization concerns.
  • IndexingService keeps the local index in sync with the user’s library.
  • AppDatabase handles persistence, migrations, and query-heavy workflows.

Tech Stack

  • Swift 6.2
  • SwiftUI
  • Swift Observation (@Observable)
  • GRDB / SQLite
  • PhotoKit
  • AVFoundation
  • Vision
  • Optional diagnostics integrations:
    • Firebase Crashlytics
    • TelemetryDeck

Diagnostics Setup

This repository does not include live diagnostics credentials.

  • Crash reporting is disabled unless you add your own GoogleService-Info.plist.
  • Analytics is disabled unless you provide TELEMETRYDECK_APP_ID in the app’s Info settings.
  • A safe starter file is included at GoogleService-Info.plist.example.

To enable diagnostics locally:

  1. Copy GoogleService-Info.plist.example to GoogleService-Info.plist and replace it with your real Firebase config if you want Crashlytics.
  2. In Xcode target build settings, provide a value for TELEMETRYDECK_APP_ID if you want TelemetryDeck.

Building

The current Xcode project and scheme are still named PhotoShelf, while the product and app branding are Phototagger.

Build in Xcode:

  • Open PhotoShelf.xcodeproj
  • Select the PhotoShelf scheme
  • Run on an iPhone simulator or device running iOS 18.6+

Command line build:

xcodebuild -project PhotoShelf.xcodeproj -scheme PhotoShelf -destination 'generic/platform=iOS Simulator' build

Key Areas

  • Services/AppState.swift for state orchestration and app-level coordination
  • Services/IndexingService.swift for PhotoKit indexing and perceptual hashing flow
  • Database/AppDatabase.swift for schema and query-heavy persistence work
  • Views/Inbox/ for the focused inbox sprint workflow
  • Views/Cleanup/ for cleanup tooling and duplicate detection UX
  • Journal.md for the engineering story, tradeoffs, and debugging history

About

SwiftUI iPhone app for large photo libraries with local indexing, duplicate detection, and inbox-first cleanup workflows.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages